From d1d08963fb6c598d006cf913e5470b144a1de1d5 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 27 Jun 2024 21:35:39 -0700 Subject: [PATCH 001/996] Initial commit --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..2c60eb5d1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Yaak App + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From a63b485b955efae094ab7374f9bd187860c1d71c Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 27 Jun 2024 21:44:45 -0700 Subject: [PATCH 002/996] Move plugins to this repo --- .gitignore | 133 ++ plugins/exporter-curl/package-lock.json | 1544 ++++++++++++++++ plugins/exporter-curl/package.json | 7 + plugins/exporter-curl/src/index.ts | 76 + plugins/exporter-curl/tests/index.test.ts | 177 ++ plugins/exporter-curl/vite.config.js | 15 + plugins/filter-jsonpath/package-lock.json | 182 ++ plugins/filter-jsonpath/package.json | 10 + plugins/filter-jsonpath/src/index.ts | 7 + plugins/filter-jsonpath/vite.config.js | 15 + plugins/filter-xpath/package-lock.json | 32 + plugins/filter-xpath/package.json | 8 + plugins/filter-xpath/src/index.ts | 10 + plugins/filter-xpath/vite.config.js | 15 + plugins/importer-curl/package-lock.json | 1562 +++++++++++++++++ plugins/importer-curl/package.json | 11 + plugins/importer-curl/src/index.ts | 419 +++++ plugins/importer-curl/tests/index.test.ts | 341 ++++ plugins/importer-curl/vite.config.js | 15 + plugins/importer-insomnia/package-lock.json | 26 + plugins/importer-insomnia/package.json | 7 + plugins/importer-insomnia/src/index.ts | 280 +++ plugins/importer-insomnia/vite.config.js | 15 + plugins/importer-postman/package-lock.json | 1505 ++++++++++++++++ plugins/importer-postman/package.json | 7 + plugins/importer-postman/src/index.ts | 253 +++ .../tests/fixtures/nested.json | 38 + plugins/importer-postman/tests/index.test.ts | 91 + plugins/importer-postman/tsconfig.json | 23 + plugins/importer-postman/vite.config.js | 15 + plugins/importer-yaak/package-lock.json | 12 + plugins/importer-yaak/package.json | 4 + plugins/importer-yaak/src/index.ts | 29 + plugins/importer-yaak/tests/index.test.ts | 32 + plugins/importer-yaak/vite.config.js | 15 + 35 files changed, 6931 insertions(+) create mode 100644 .gitignore create mode 100644 plugins/exporter-curl/package-lock.json create mode 100644 plugins/exporter-curl/package.json create mode 100644 plugins/exporter-curl/src/index.ts create mode 100644 plugins/exporter-curl/tests/index.test.ts create mode 100644 plugins/exporter-curl/vite.config.js create mode 100644 plugins/filter-jsonpath/package-lock.json create mode 100644 plugins/filter-jsonpath/package.json create mode 100644 plugins/filter-jsonpath/src/index.ts create mode 100644 plugins/filter-jsonpath/vite.config.js create mode 100644 plugins/filter-xpath/package-lock.json create mode 100644 plugins/filter-xpath/package.json create mode 100644 plugins/filter-xpath/src/index.ts create mode 100644 plugins/filter-xpath/vite.config.js create mode 100644 plugins/importer-curl/package-lock.json create mode 100644 plugins/importer-curl/package.json create mode 100644 plugins/importer-curl/src/index.ts create mode 100644 plugins/importer-curl/tests/index.test.ts create mode 100644 plugins/importer-curl/vite.config.js create mode 100644 plugins/importer-insomnia/package-lock.json create mode 100644 plugins/importer-insomnia/package.json create mode 100644 plugins/importer-insomnia/src/index.ts create mode 100644 plugins/importer-insomnia/vite.config.js create mode 100644 plugins/importer-postman/package-lock.json create mode 100644 plugins/importer-postman/package.json create mode 100644 plugins/importer-postman/src/index.ts create mode 100644 plugins/importer-postman/tests/fixtures/nested.json create mode 100644 plugins/importer-postman/tests/index.test.ts create mode 100644 plugins/importer-postman/tsconfig.json create mode 100644 plugins/importer-postman/vite.config.js create mode 100644 plugins/importer-yaak/package-lock.json create mode 100644 plugins/importer-yaak/package.json create mode 100644 plugins/importer-yaak/src/index.ts create mode 100644 plugins/importer-yaak/tests/index.test.ts create mode 100644 plugins/importer-yaak/vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..ec5792a8b --- /dev/null +++ b/.gitignore @@ -0,0 +1,133 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# Other +build +.idea diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json new file mode 100644 index 000000000..c8ee5b8a2 --- /dev/null +++ b/plugins/exporter-curl/package-lock.json @@ -0,0 +1,1544 @@ +{ + "name": "exporter-curl", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "exporter-curl", + "version": "0.0.1", + "devDependencies": { + "vitest": "^1.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", + "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", + "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", + "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", + "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", + "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", + "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", + "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", + "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", + "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", + "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", + "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", + "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", + "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", + "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", + "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", + "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@vitest/expect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.6.0", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", + "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", + "dev": true + }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mlly": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.0.tgz", + "integrity": "sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.0", + "ufo": "^1.5.3" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/pkg-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz", + "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==", + "dev": true, + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.6.1", + "pathe": "^1.1.2" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/rollup": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", + "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.17.2", + "@rollup/rollup-android-arm64": "4.17.2", + "@rollup/rollup-darwin-arm64": "4.17.2", + "@rollup/rollup-darwin-x64": "4.17.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", + "@rollup/rollup-linux-arm-musleabihf": "4.17.2", + "@rollup/rollup-linux-arm64-gnu": "4.17.2", + "@rollup/rollup-linux-arm64-musl": "4.17.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", + "@rollup/rollup-linux-riscv64-gnu": "4.17.2", + "@rollup/rollup-linux-s390x-gnu": "4.17.2", + "@rollup/rollup-linux-x64-gnu": "4.17.2", + "@rollup/rollup-linux-x64-musl": "4.17.2", + "@rollup/rollup-win32-arm64-msvc": "4.17.2", + "@rollup/rollup-win32-ia32-msvc": "4.17.2", + "@rollup/rollup-win32-x64-msvc": "4.17.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", + "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", + "dev": true, + "dependencies": { + "js-tokens": "^9.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/tinybench": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ufo": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", + "dev": true + }, + "node_modules/vite": { + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", + "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", + "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.6.0", + "@vitest/runner": "1.6.0", + "@vitest/snapshot": "1.6.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.0", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.0", + "@vitest/ui": "1.6.0", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json new file mode 100644 index 000000000..4674e1a0e --- /dev/null +++ b/plugins/exporter-curl/package.json @@ -0,0 +1,7 @@ +{ + "name": "exporter-curl", + "version": "0.0.1", + "devDependencies": { + "vitest": "^1.4.0" + } +} diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts new file mode 100644 index 000000000..44c99a1f8 --- /dev/null +++ b/plugins/exporter-curl/src/index.ts @@ -0,0 +1,76 @@ +import { HttpRequest } from '../../../src-web/lib/models'; + +const NEWLINE = '\\\n '; + +export function pluginHookExport(_: any, request: Partial) { + const xs = ['curl']; + + // Add method and URL all on first line + if (request.method) xs.push('-X', request.method); + if (request.url) xs.push(quote(request.url)); + + xs.push(NEWLINE); + + // Add URL params + for (const p of (request.urlParameters ?? []).filter(onlyEnabled)) { + xs.push('--url-query', quote(`${p.name}=${p.value}`)); + xs.push(NEWLINE); + } + + // Add headers + for (const h of (request.headers ?? []).filter(onlyEnabled)) { + xs.push('--header', quote(`${h.name}: ${h.value}`)); + xs.push(NEWLINE); + } + + // Add form params + if (Array.isArray(request.body?.form)) { + const flag = request.bodyType === 'multipart/form-data' ? '--form' : '--data'; + for (const p of (request.body?.form ?? []).filter(onlyEnabled)) { + if (p.file) { + let v = `${p.name}=@${p.file}`; + v += p.contentType ? `;type=${p.contentType}` : ''; + xs.push(flag, v); + } else { + xs.push(flag, quote(`${p.name}=${p.value}`)); + } + xs.push(NEWLINE); + } + } else if (typeof request.body?.text === 'string') { + // --data-raw $'...' to do special ANSI C quoting + xs.push('--data-raw', `$${quote(request.body.text)}`); + xs.push(NEWLINE); + } + + // Add basic/digest authentication + if (request.authenticationType === 'basic' || request.authenticationType === 'digest') { + if (request.authenticationType === 'digest') xs.push('--digest'); + xs.push( + '--user', + quote(`${request.authentication?.username ?? ''}:${request.authentication?.password ?? ''}`), + ); + xs.push(NEWLINE); + } + + // Add bearer authentication + if (request.authenticationType === 'bearer') { + xs.push('--header', quote(`Authorization: Bearer ${request.authentication?.token ?? ''}`)); + xs.push(NEWLINE); + } + + // Remove trailing newline + if (xs[xs.length - 1] === NEWLINE) { + xs.splice(xs.length - 1, 1); + } + + return xs.join(' '); +} + +function quote(arg: string): string { + const escaped = arg.replace(/'/g, "\\'"); + return `'${escaped}'`; +} + +function onlyEnabled(v: { name?: string; enabled?: boolean }): boolean { + return v.enabled !== false && !!v.name; +} diff --git a/plugins/exporter-curl/tests/index.test.ts b/plugins/exporter-curl/tests/index.test.ts new file mode 100644 index 000000000..caceb95fb --- /dev/null +++ b/plugins/exporter-curl/tests/index.test.ts @@ -0,0 +1,177 @@ +import { describe, expect, test } from 'vitest'; +import { pluginHookExport } from '../src'; + +const ctx = {}; + +describe('exporter-curl', () => { + test('Exports GET with params', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + urlParameters: [ + { name: 'a', value: 'aaa' }, + { name: 'b', value: 'bbb', enabled: true }, + { name: 'c', value: 'ccc', enabled: false }, + ], + }), + ).toEqual( + [`curl 'https://yaak.app'`, `--url-query 'a=aaa'`, `--url-query 'b=bbb'`].join(` \\\n `), + ); + }); + test('Exports POST with url form data', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + method: 'POST', + bodyType: 'application/x-www-form-urlencoded', + body: { + form: [ + { name: 'a', value: 'aaa' }, + { name: 'b', value: 'bbb', enabled: true }, + { name: 'c', value: 'ccc', enabled: false }, + ], + }, + }), + ).toEqual( + [`curl -X POST 'https://yaak.app'`, `--data 'a=aaa'`, `--data 'b=bbb'`].join(` \\\n `), + ); + }); + + test('Exports PUT with multipart form', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + method: 'PUT', + bodyType: 'multipart/form-data', + body: { + form: [ + { name: 'a', value: 'aaa' }, + { name: 'b', value: 'bbb', enabled: true }, + { name: 'c', value: 'ccc', enabled: false }, + { name: 'f', file: '/foo/bar.png', contentType: 'image/png' }, + ], + }, + }), + ).toEqual( + [ + `curl -X PUT 'https://yaak.app'`, + `--form 'a=aaa'`, + `--form 'b=bbb'`, + `--form f=@/foo/bar.png;type=image/png`, + ].join(` \\\n `), + ); + }); + + test('Exports JSON body', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + method: 'POST', + bodyType: 'application/json', + body: { + text: `{"foo":"bar's"}`, + }, + headers: [{ name: 'Content-Type', value: 'application/json' }], + }), + ).toEqual( + [ + `curl -X POST 'https://yaak.app'`, + `--header 'Content-Type: application/json'`, + `--data-raw $'{"foo":"bar\\'s"}'`, + ].join(` \\\n `), + ); + }); + + test('Exports multi-line JSON body', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + method: 'POST', + bodyType: 'application/json', + body: { + text: `{"foo":"bar",\n"baz":"qux"}`, + }, + headers: [{ name: 'Content-Type', value: 'application/json' }], + }), + ).toEqual( + [ + `curl -X POST 'https://yaak.app'`, + `--header 'Content-Type: application/json'`, + `--data-raw $'{"foo":"bar",\n"baz":"qux"}'`, + ].join(` \\\n `), + ); + }); + + test('Exports headers', () => { + expect( + pluginHookExport(ctx, { + headers: [ + { name: 'a', value: 'aaa' }, + { name: 'b', value: 'bbb', enabled: true }, + { name: 'c', value: 'ccc', enabled: false }, + ], + }), + ).toEqual([`curl`, `--header 'a: aaa'`, `--header 'b: bbb'`].join(` \\\n `)); + }); + + test('Basic auth', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + authenticationType: 'basic', + authentication: { + username: 'user', + password: 'pass', + }, + }), + ).toEqual([`curl 'https://yaak.app'`, `--user 'user:pass'`].join(` \\\n `)); + }); + + test('Broken basic auth', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + authenticationType: 'basic', + authentication: {}, + }), + ).toEqual([`curl 'https://yaak.app'`, `--user ':'`].join(` \\\n `)); + }); + + test('Digest auth', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + authenticationType: 'digest', + authentication: { + username: 'user', + password: 'pass', + }, + }), + ).toEqual([`curl 'https://yaak.app'`, `--digest --user 'user:pass'`].join(` \\\n `)); + }); + + test('Bearer auth', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + authenticationType: 'bearer', + authentication: { + token: 'tok', + }, + }), + ).toEqual([`curl 'https://yaak.app'`, `--header 'Authorization: Bearer tok'`].join(` \\\n `)); + }); + + test('Broken bearer auth', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + authenticationType: 'bearer', + authentication: { + username: 'user', + password: 'pass', + }, + }), + ).toEqual([`curl 'https://yaak.app'`, `--header 'Authorization: Bearer '`].join(` \\\n `)); + }); +}); diff --git a/plugins/exporter-curl/vite.config.js b/plugins/exporter-curl/vite.config.js new file mode 100644 index 000000000..787b33455 --- /dev/null +++ b/plugins/exporter-curl/vite.config.js @@ -0,0 +1,15 @@ +import { resolve } from 'path'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + fileName: 'index', + formats: ['es'], + }, + emptyOutDir: true, + sourcemap: true, + outDir: resolve(__dirname, 'build'), + }, +}); diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json new file mode 100644 index 000000000..4bacbcc84 --- /dev/null +++ b/plugins/filter-jsonpath/package-lock.json @@ -0,0 +1,182 @@ +{ + "name": "filter-jsonpath", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "filter-jsonpath", + "version": "0.0.1", + "dependencies": { + "jsonpath": "^1.1.1" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } + }, + "node_modules/@types/jsonpath": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.4.tgz", + "integrity": "sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA==", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "dependencies": { + "escodegen": "^1.8.1" + } + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "engines": { + "node": ">=0.10.0" + } + } + } +} diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json new file mode 100644 index 000000000..ce608c093 --- /dev/null +++ b/plugins/filter-jsonpath/package.json @@ -0,0 +1,10 @@ +{ + "name": "filter-jsonpath", + "version": "0.0.1", + "dependencies": { + "jsonpath": "^1.1.1" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } +} diff --git a/plugins/filter-jsonpath/src/index.ts b/plugins/filter-jsonpath/src/index.ts new file mode 100644 index 000000000..7678d148b --- /dev/null +++ b/plugins/filter-jsonpath/src/index.ts @@ -0,0 +1,7 @@ +import jp from 'jsonpath'; + +export function pluginHookResponseFilter(_ctx: any, args: { filter: string; body: string }) { + const parsed = JSON.parse(args.body); + const filtered = jp.query(parsed, args.filter); + return JSON.stringify(filtered, null, 2); +} diff --git a/plugins/filter-jsonpath/vite.config.js b/plugins/filter-jsonpath/vite.config.js new file mode 100644 index 000000000..787b33455 --- /dev/null +++ b/plugins/filter-jsonpath/vite.config.js @@ -0,0 +1,15 @@ +import { resolve } from 'path'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + fileName: 'index', + formats: ['es'], + }, + emptyOutDir: true, + sourcemap: true, + outDir: resolve(__dirname, 'build'), + }, +}); diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json new file mode 100644 index 000000000..9fb40cd46 --- /dev/null +++ b/plugins/filter-xpath/package-lock.json @@ -0,0 +1,32 @@ +{ + "name": "filter-xpath", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "filter-xpath", + "version": "0.0.1", + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "xpath": "^0.0.34" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/xpath": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", + "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==", + "engines": { + "node": ">=0.6.0" + } + } + } +} diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json new file mode 100644 index 000000000..897faa3d4 --- /dev/null +++ b/plugins/filter-xpath/package.json @@ -0,0 +1,8 @@ +{ + "name": "filter-xpath", + "version": "0.0.1", + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "xpath": "^0.0.34" + } +} diff --git a/plugins/filter-xpath/src/index.ts b/plugins/filter-xpath/src/index.ts new file mode 100644 index 000000000..35fd21de8 --- /dev/null +++ b/plugins/filter-xpath/src/index.ts @@ -0,0 +1,10 @@ +import { DOMParser } from '@xmldom/xmldom'; +import xpath from 'xpath'; + +export function pluginHookResponseFilter( + _ctx: any, + { filter, body }: { filter: string; body: string }, +) { + const doc = new DOMParser().parseFromString(body, 'text/xml'); + return `${xpath.select(filter, doc)}`; +} diff --git a/plugins/filter-xpath/vite.config.js b/plugins/filter-xpath/vite.config.js new file mode 100644 index 000000000..787b33455 --- /dev/null +++ b/plugins/filter-xpath/vite.config.js @@ -0,0 +1,15 @@ +import { resolve } from 'path'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + fileName: 'index', + formats: ['es'], + }, + emptyOutDir: true, + sourcemap: true, + outDir: resolve(__dirname, 'build'), + }, +}); diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json new file mode 100644 index 000000000..2846dda89 --- /dev/null +++ b/plugins/importer-curl/package-lock.json @@ -0,0 +1,1562 @@ +{ + "name": "importer-curl", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "importer-curl", + "version": "0.0.1", + "dependencies": { + "shell-quote": "^1.8.1" + }, + "devDependencies": { + "@types/shell-quote": "^1.7.5", + "vitest": "^1.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", + "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", + "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", + "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", + "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", + "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", + "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", + "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", + "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", + "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", + "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", + "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", + "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", + "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", + "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", + "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", + "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/shell-quote": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@types/shell-quote/-/shell-quote-1.7.5.tgz", + "integrity": "sha512-+UE8GAGRPbJVQDdxi16dgadcBfQ+KG2vgZhV1+3A1XmHbmwcdwhCUwIdy+d3pAGrbvgRoVSjeI9vOWyq376Yzw==", + "dev": true + }, + "node_modules/@vitest/expect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.6.0", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", + "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", + "dev": true + }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mlly": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.0.tgz", + "integrity": "sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.0", + "ufo": "^1.5.3" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/pkg-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz", + "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==", + "dev": true, + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.6.1", + "pathe": "^1.1.2" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/rollup": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", + "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.17.2", + "@rollup/rollup-android-arm64": "4.17.2", + "@rollup/rollup-darwin-arm64": "4.17.2", + "@rollup/rollup-darwin-x64": "4.17.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", + "@rollup/rollup-linux-arm-musleabihf": "4.17.2", + "@rollup/rollup-linux-arm64-gnu": "4.17.2", + "@rollup/rollup-linux-arm64-musl": "4.17.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", + "@rollup/rollup-linux-riscv64-gnu": "4.17.2", + "@rollup/rollup-linux-s390x-gnu": "4.17.2", + "@rollup/rollup-linux-x64-gnu": "4.17.2", + "@rollup/rollup-linux-x64-musl": "4.17.2", + "@rollup/rollup-win32-arm64-msvc": "4.17.2", + "@rollup/rollup-win32-ia32-msvc": "4.17.2", + "@rollup/rollup-win32-x64-msvc": "4.17.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", + "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", + "dev": true, + "dependencies": { + "js-tokens": "^9.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/tinybench": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ufo": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", + "dev": true + }, + "node_modules/vite": { + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", + "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", + "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.6.0", + "@vitest/runner": "1.6.0", + "@vitest/snapshot": "1.6.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.0", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.0", + "@vitest/ui": "1.6.0", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json new file mode 100644 index 000000000..989b2d662 --- /dev/null +++ b/plugins/importer-curl/package.json @@ -0,0 +1,11 @@ +{ + "name": "importer-curl", + "version": "0.0.1", + "dependencies": { + "shell-quote": "^1.8.1" + }, + "devDependencies": { + "@types/shell-quote": "^1.7.5", + "vitest": "^1.4.0" + } +} diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts new file mode 100644 index 000000000..b6092b242 --- /dev/null +++ b/plugins/importer-curl/src/index.ts @@ -0,0 +1,419 @@ +import { ControlOperator, parse, ParseEntry } from 'shell-quote'; +import { + Environment, + Folder, + HttpRequest, + HttpUrlParameter, + Model, + Workspace, +} from '../../../src-web/lib/models'; + +type AtLeast = Partial & Pick; + +interface ExportResources { + workspaces: AtLeast[]; + environments: AtLeast[]; + httpRequests: AtLeast[]; + folders: AtLeast[]; +} + +const DATA_FLAGS = ['d', 'data', 'data-raw', 'data-urlencode', 'data-binary', 'data-ascii']; +const SUPPORTED_ARGS = [ + ['url'], // Specify the URL explicitly + ['user', 'u'], // Authentication + ['digest'], // Apply auth as digest + ['header', 'H'], + ['cookie', 'b'], + ['get', 'G'], // Put the post data in the URL + ['d', 'data'], // Add url encoded data + ['data-raw'], + ['data-urlencode'], + ['data-binary'], + ['data-ascii'], + ['form', 'F'], // Add multipart data + ['request', 'X'], // Request method + DATA_FLAGS, +].flatMap((v) => v); + +type Pair = string | boolean; + +type PairsByName = Record; + +export function pluginHookImport(_: any, rawData: string) { + if (!rawData.match(/^\s*curl /)) { + return null; + } + + const commands: ParseEntry[][] = []; + + // Replace non-escaped newlines with semicolons to make parsing easier + // NOTE: This is really slow in debug build but fast in release mode + const normalizedData = rawData.replace(/\ncurl/g, '; curl'); + + let currentCommand: ParseEntry[] = []; + + const parsed = parse(normalizedData); + + // Break up `-XPOST` into `-X POST` + const normalizedParseEntries = parsed.flatMap((entry) => { + if ( + typeof entry === 'string' && + entry.startsWith('-') && + !entry.startsWith('--') && + entry.length > 2 + ) { + return [entry.slice(0, 2), entry.slice(2)]; + } + return entry; + }); + + for (const parseEntry of normalizedParseEntries) { + if (typeof parseEntry === 'string') { + if (parseEntry.startsWith('$')) { + currentCommand.push(parseEntry.slice(1)); + } else { + currentCommand.push(parseEntry); + } + continue; + } + + if ('comment' in parseEntry) { + continue; + } + + const { op } = parseEntry as { op: 'glob'; pattern: string } | { op: ControlOperator }; + + // `;` separates commands + if (op === ';') { + commands.push(currentCommand); + currentCommand = []; + continue; + } + + if (op?.startsWith('$')) { + // Handle the case where literal like -H $'Header: \'Some Quoted Thing\'' + const str = op.slice(2, op.length - 1).replace(/\\'/g, "'"); + + currentCommand.push(str); + continue; + } + + if (op === 'glob') { + currentCommand.push((parseEntry as { op: 'glob'; pattern: string }).pattern); + } + } + + commands.push(currentCommand); + + const workspace: ExportResources['workspaces'][0] = { + model: 'workspace', + id: generateId('workspace'), + name: 'Curl Import', + }; + + const requests: ExportResources['httpRequests'] = commands + .filter((command) => command[0] === 'curl') + .map((v) => importCommand(v, workspace.id)); + + return { + resources: { + httpRequests: requests, + workspaces: [workspace], + }, + }; +} + +function importCommand(parseEntries: ParseEntry[], workspaceId: string) { + // ~~~~~~~~~~~~~~~~~~~~~ // + // Collect all the flags // + // ~~~~~~~~~~~~~~~~~~~~~ // + const pairsByName: PairsByName = {}; + const singletons: ParseEntry[] = []; + + // Start at 1 so we can skip the ^curl part + for (let i = 1; i < parseEntries.length; i++) { + let parseEntry = parseEntries[i]; + if (typeof parseEntry === 'string') { + parseEntry = parseEntry.trim(); + } + + if (typeof parseEntry === 'string' && parseEntry.match(/^-{1,2}[\w-]+/)) { + const isSingleDash = parseEntry[0] === '-' && parseEntry[1] !== '-'; + let name = parseEntry.replace(/^-{1,2}/, ''); + + if (!SUPPORTED_ARGS.includes(name)) { + continue; + } + + let value; + const nextEntry = parseEntries[i + 1]; + if (isSingleDash && name.length > 1) { + // Handle squished arguments like -XPOST + value = name.slice(1); + name = name.slice(0, 1); + } else if (typeof nextEntry === 'string' && !nextEntry.startsWith('-')) { + // Next arg is not a flag, so assign it as the value + value = nextEntry; + i++; // Skip next one + } else { + value = true; + } + + pairsByName[name] = pairsByName[name] || []; + pairsByName[name]!.push(value); + } else if (parseEntry) { + singletons.push(parseEntry); + } + } + + // ~~~~~~~~~~~~~~~~~ // + // Build the request // + // ~~~~~~~~~~~~~~~~~ // + + // Url & parameters + + let urlParameters: HttpUrlParameter[]; + let url: string; + + const urlArg = getPairValue(pairsByName, (singletons[0] as string) || '', ['url']); + const [baseUrl, search] = splitOnce(urlArg, '?'); + urlParameters = + search?.split('&').map((p) => { + const v = splitOnce(p, '='); + return { name: v[0] ?? '', value: v[1] ?? '', enabled: true }; + }) ?? []; + + url = baseUrl ?? urlArg; + + // Authentication + const [username, password] = getPairValue(pairsByName, '', ['u', 'user']).split(/:(.*)$/); + + const isDigest = getPairValue(pairsByName, false, ['digest']); + const authenticationType = username ? (isDigest ? 'digest' : 'basic') : null; + const authentication = username + ? { + username: username.trim(), + password: (password ?? '').trim(), + } + : {}; + + // Headers + const headers = [ + ...((pairsByName['header'] as string[] | undefined) || []), + ...((pairsByName['H'] as string[] | undefined) || []), + ].map((header) => { + const [name, value] = header.split(/:(.*)$/); + // remove final colon from header name if present + if (!value) { + return { + name: (name ?? '').trim().replace(/;$/, ''), + value: '', + enabled: true, + }; + } + return { + name: (name ?? '').trim(), + value: value.trim(), + enabled: true, + }; + }); + + // Cookies + const cookieHeaderValue = [ + ...((pairsByName['cookie'] as string[] | undefined) || []), + ...((pairsByName['b'] as string[] | undefined) || []), + ] + .map((str) => { + const name = str.split('=', 1)[0]; + const value = str.replace(`${name}=`, ''); + return `${name}=${value}`; + }) + .join('; '); + + // Convert cookie value to header + const existingCookieHeader = headers.find((header) => header.name.toLowerCase() === 'cookie'); + + if (cookieHeaderValue && existingCookieHeader) { + // Has existing cookie header, so let's update it + existingCookieHeader.value += `; ${cookieHeaderValue}`; + } else if (cookieHeaderValue) { + // No existing cookie header, so let's make a new one + headers.push({ + name: 'Cookie', + value: cookieHeaderValue, + enabled: true, + }); + } + + ///Body (Text or Blob) + const dataParameters = pairsToDataParameters(pairsByName); + const contentTypeHeader = headers.find((header) => header.name.toLowerCase() === 'content-type'); + const mimeType = contentTypeHeader ? contentTypeHeader.value.split(';')[0] : null; + + // Body (Multipart Form Data) + const formDataParams = [ + ...((pairsByName['form'] as string[] | undefined) || []), + ...((pairsByName['F'] as string[] | undefined) || []), + ].map((str) => { + const parts = str.split('='); + const name = parts[0] ?? ''; + const value = parts[1] ?? ''; + const item: { name: string; value?: string; file?: string; enabled: boolean } = { + name, + enabled: true, + }; + + if (value.indexOf('@') === 0) { + item['file'] = value.slice(1); + } else { + item['value'] = value; + } + + return item; + }); + + // Body + let body = {}; + let bodyType: string | null = null; + const bodyAsGET = getPairValue(pairsByName, false, ['G', 'get']); + + if (dataParameters.length > 0 && bodyAsGET) { + urlParameters.push(...dataParameters); + } else if ( + dataParameters.length > 0 && + (mimeType == null || mimeType === 'application/x-www-form-urlencoded') + ) { + bodyType = mimeType ?? 'application/x-www-form-urlencoded'; + body = { + form: dataParameters.map((parameter) => ({ + ...parameter, + name: decodeURIComponent(parameter.name || ''), + value: decodeURIComponent(parameter.value || ''), + })), + }; + headers.push({ + name: 'Content-Type', + value: 'application/x-www-form-urlencoded', + enabled: true, + }); + } else if (dataParameters.length > 0) { + bodyType = + mimeType === 'application/json' || mimeType === 'text/xml' || mimeType === 'text/plain' + ? mimeType + : 'other'; + body = { + text: dataParameters + .map(({ name, value }) => (name && value ? `${name}=${value}` : name || value)) + .join('&'), + }; + } else if (formDataParams.length) { + bodyType = mimeType ?? 'multipart/form-data'; + body = { + form: formDataParams, + }; + if (mimeType == null) { + headers.push({ + name: 'Content-Type', + value: 'multipart/form-data', + enabled: true, + }); + } + } + + // Method + let method = getPairValue(pairsByName, '', ['X', 'request']).toUpperCase(); + + if (method === '' && body) { + method = 'text' in body || 'form' in body ? 'POST' : 'GET'; + } + + const request: ExportResources['httpRequests'][0] = { + id: generateId('http_request'), + model: 'http_request', + workspaceId, + name: '', + urlParameters, + url, + method, + headers, + authentication, + authenticationType, + body, + bodyType, + folderId: null, + sortPriority: 0, + }; + + return request; +} + +interface DataParameter { + name: string; + value: string; + contentType?: string; + filePath?: string; + enabled?: boolean; +} + +function pairsToDataParameters(keyedPairs: PairsByName): DataParameter[] { + let dataParameters: DataParameter[] = []; + + for (const flagName of DATA_FLAGS) { + const pairs = keyedPairs[flagName]; + + if (!pairs || pairs.length === 0) { + continue; + } + + for (const p of pairs) { + if (typeof p !== 'string') continue; + + const [name, value] = p.split('='); + if (p.startsWith('@')) { + // Yaak doesn't support files in url-encoded data, so + dataParameters.push({ + name: name ?? '', + value: '', + filePath: p.slice(1), + enabled: true, + }); + } else { + dataParameters.push({ + name: name ?? '', + value: flagName === 'data-urlencode' ? encodeURIComponent(value ?? '') : value ?? '', + enabled: true, + }); + } + } + } + + return dataParameters; +} + +const getPairValue = ( + pairsByName: PairsByName, + defaultValue: T, + names: string[], +) => { + for (const name of names) { + if (pairsByName[name] && pairsByName[name]!.length) { + return pairsByName[name]![0] as T; + } + } + + return defaultValue; +}; + +function splitOnce(str: string, sep: string): string[] { + const index = str.indexOf(sep); + if (index > -1) { + return [str.slice(0, index), str.slice(index + 1)]; + } + return [str]; +} + +const idCount: Partial> = {}; +function generateId(model: Model['model']): string { + idCount[model] = (idCount[model] ?? -1) + 1; + return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`; +} diff --git a/plugins/importer-curl/tests/index.test.ts b/plugins/importer-curl/tests/index.test.ts new file mode 100644 index 000000000..f2aac3706 --- /dev/null +++ b/plugins/importer-curl/tests/index.test.ts @@ -0,0 +1,341 @@ +import { describe, expect, test } from 'vitest'; +import { HttpRequest, Model, Workspace } from '../../../src-web/lib/models'; +import { pluginHookImport } from '../src'; + +const ctx = {}; + +describe('importer-curl', () => { + test('Imports basic GET', () => { + expect(pluginHookImport(ctx, 'curl https://yaak.app')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + }), + ], + }, + }); + }); + + test('Explicit URL', () => { + expect(pluginHookImport(ctx, 'curl --url https://yaak.app')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + }), + ], + }, + }); + }); + + test('Missing URL', () => { + expect(pluginHookImport(ctx, 'curl -X POST')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + method: 'POST', + }), + ], + }, + }); + }); + + test('URL between', () => { + expect(pluginHookImport(ctx, 'curl -v https://yaak.app -X POST')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + method: 'POST', + }), + ], + }, + }); + }); + + test('Random flags', () => { + expect(pluginHookImport(ctx, 'curl --random -Z -Y -S --foo https://yaak.app')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + }), + ], + }, + }); + }); + + test('Imports --request method', () => { + expect(pluginHookImport(ctx, 'curl --request POST https://yaak.app')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + method: 'POST', + }), + ], + }, + }); + }); + + test('Imports -XPOST method', () => { + expect(pluginHookImport(ctx, 'curl -XPOST --request POST https://yaak.app')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + method: 'POST', + }), + ], + }, + }); + }); + + test('Imports multiple requests', () => { + expect( + pluginHookImport( + ctx, + 'curl \\\n https://yaak.app\necho "foo"\ncurl example.com;curl foo.com', + ), + ).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ url: 'https://yaak.app' }), + baseRequest({ url: 'example.com' }), + baseRequest({ url: 'foo.com' }), + ], + }, + }); + }); + + test('Imports form data', () => { + expect( + pluginHookImport(ctx, 'curl -X POST -F "a=aaa" -F b=bbb" -F f=@filepath https://yaak.app'), + ).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + method: 'POST', + url: 'https://yaak.app', + headers: [ + { + name: 'Content-Type', + value: 'multipart/form-data', + enabled: true, + }, + ], + bodyType: 'multipart/form-data', + body: { + form: [ + { enabled: true, name: 'a', value: 'aaa' }, + { enabled: true, name: 'b', value: 'bbb' }, + { enabled: true, name: 'f', file: 'filepath' }, + ], + }, + }), + ], + }, + }); + }); + + test('Imports data params as form url-encoded', () => { + expect(pluginHookImport(ctx, 'curl -d a -d b -d c=ccc https://yaak.app')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + method: 'POST', + url: 'https://yaak.app', + bodyType: 'application/x-www-form-urlencoded', + headers: [ + { + name: 'Content-Type', + value: 'application/x-www-form-urlencoded', + enabled: true, + }, + ], + body: { + form: [ + { name: 'a', value: '', enabled: true }, + { name: 'b', value: '', enabled: true }, + { name: 'c', value: 'ccc', enabled: true }, + ], + }, + }), + ], + }, + }); + }); + + test('Imports data params as text', () => { + expect( + pluginHookImport(ctx, 'curl -H Content-Type:text/plain -d a -d b -d c=ccc https://yaak.app'), + ).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + method: 'POST', + url: 'https://yaak.app', + headers: [{ name: 'Content-Type', value: 'text/plain', enabled: true }], + bodyType: 'text/plain', + body: { text: 'a&b&c=ccc' }, + }), + ], + }, + }); + }); + + test('Imports multi-line JSON', () => { + expect( + pluginHookImport( + ctx, + `curl -H Content-Type:application/json -d $'{\n "foo":"bar"\n}' https://yaak.app`, + ), + ).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + method: 'POST', + url: 'https://yaak.app', + headers: [{ name: 'Content-Type', value: 'application/json', enabled: true }], + bodyType: 'application/json', + body: { text: '{\n "foo":"bar"\n}' }, + }), + ], + }, + }); + }); + + test('Imports multiple headers', () => { + expect( + pluginHookImport(ctx, 'curl -H Foo:bar --header Name -H AAA:bbb -H :ccc https://yaak.app'), + ).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + headers: [ + { name: 'Name', value: '', enabled: true }, + { name: 'Foo', value: 'bar', enabled: true }, + { name: 'AAA', value: 'bbb', enabled: true }, + { name: '', value: 'ccc', enabled: true }, + ], + }), + ], + }, + }); + }); + + test('Imports basic auth', () => { + expect(pluginHookImport(ctx, 'curl --user user:pass https://yaak.app')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + authenticationType: 'basic', + authentication: { + username: 'user', + password: 'pass', + }, + }), + ], + }, + }); + }); + + test('Imports digest auth', () => { + expect(pluginHookImport(ctx, 'curl --digest --user user:pass https://yaak.app')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + authenticationType: 'digest', + authentication: { + username: 'user', + password: 'pass', + }, + }), + ], + }, + }); + }); + + test('Imports cookie as header', () => { + expect(pluginHookImport(ctx, 'curl --cookie "foo=bar" https://yaak.app')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + headers: [{ name: 'Cookie', value: 'foo=bar', enabled: true }], + }), + ], + }, + }); + }); + + test('Imports query params from the URL', () => { + expect(pluginHookImport(ctx, 'curl "https://yaak.app?foo=bar&baz=a%20a"')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + urlParameters: [ + { name: 'foo', value: 'bar', enabled: true }, + { name: 'baz', value: 'a%20a', enabled: true }, + ], + }), + ], + }, + }); + }); +}); + +const idCount: Partial> = {}; + +function baseRequest(mergeWith: Partial) { + idCount.http_request = (idCount.http_request ?? -1) + 1; + return { + id: `GENERATE_ID::HTTP_REQUEST_${idCount.http_request}`, + model: 'http_request', + authentication: {}, + authenticationType: null, + body: {}, + bodyType: null, + folderId: null, + headers: [], + method: 'GET', + name: '', + sortPriority: 0, + url: '', + urlParameters: [], + workspaceId: `GENERATE_ID::WORKSPACE_${idCount.workspace}`, + ...mergeWith, + }; +} + +function baseWorkspace(mergeWith: Partial = {}) { + idCount.workspace = (idCount.workspace ?? -1) + 1; + return { + id: `GENERATE_ID::WORKSPACE_${idCount.workspace}`, + model: 'workspace', + name: 'Curl Import', + ...mergeWith, + }; +} diff --git a/plugins/importer-curl/vite.config.js b/plugins/importer-curl/vite.config.js new file mode 100644 index 000000000..787b33455 --- /dev/null +++ b/plugins/importer-curl/vite.config.js @@ -0,0 +1,15 @@ +import { resolve } from 'path'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + fileName: 'index', + formats: ['es'], + }, + emptyOutDir: true, + sourcemap: true, + outDir: resolve(__dirname, 'build'), + }, +}); diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json new file mode 100644 index 000000000..a7dd6a64c --- /dev/null +++ b/plugins/importer-insomnia/package-lock.json @@ -0,0 +1,26 @@ +{ + "name": "importer-insomnia", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "importer-insomnia", + "version": "0.0.1", + "dependencies": { + "yaml": "^2.4.2" + } + }, + "node_modules/yaml": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", + "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + } + } +} diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json new file mode 100644 index 000000000..7432d4960 --- /dev/null +++ b/plugins/importer-insomnia/package.json @@ -0,0 +1,7 @@ +{ + "name": "importer-insomnia", + "version": "0.0.1", + "dependencies": { + "yaml": "^2.4.2" + } +} diff --git a/plugins/importer-insomnia/src/index.ts b/plugins/importer-insomnia/src/index.ts new file mode 100644 index 000000000..bad5f13c3 --- /dev/null +++ b/plugins/importer-insomnia/src/index.ts @@ -0,0 +1,280 @@ +import { + Environment, + Folder, + GrpcRequest, + HttpRequest, + Workspace, +} from '../../../src-web/lib/models'; +import YAML from 'yaml'; + +type AtLeast = Partial & Pick; + +export interface ExportResources { + workspaces: AtLeast[]; + environments: AtLeast[]; + httpRequests: AtLeast[]; + grpcRequests: AtLeast[]; + folders: AtLeast[]; +} + +export function pluginHookImport(ctx: any, contents: string) { + let parsed: any; + + try { + parsed = JSON.parse(contents); + } catch (e) {} + + try { + parsed = parsed ?? YAML.parse(contents); + } catch (e) { + console.log('FAILED', e); + } + + if (!isJSObject(parsed)) return; + if (!Array.isArray(parsed.resources)) return; + + const resources: ExportResources = { + workspaces: [], + httpRequests: [], + grpcRequests: [], + environments: [], + folders: [], + }; + + // Import workspaces + const workspacesToImport = parsed.resources.filter(isWorkspace); + for (const workspaceToImport of workspacesToImport) { + const baseEnvironment = parsed.resources.find( + (r: any) => isEnvironment(r) && r.parentId === workspaceToImport._id, + ); + resources.workspaces.push({ + id: convertId(workspaceToImport._id), + createdAt: new Date(workspacesToImport.created ?? Date.now()).toISOString().replace('Z', ''), + updatedAt: new Date(workspacesToImport.updated ?? Date.now()).toISOString().replace('Z', ''), + model: 'workspace', + name: workspaceToImport.name, + variables: baseEnvironment ? parseVariables(baseEnvironment.data) : [], + }); + const environmentsToImport = parsed.resources.filter( + (r: any) => isEnvironment(r) && r.parentId === baseEnvironment?._id, + ); + resources.environments.push( + ...environmentsToImport.map((r: any) => importEnvironment(r, workspaceToImport._id)), + ); + + const nextFolder = (parentId: string) => { + const children = parsed.resources.filter((r: any) => r.parentId === parentId); + let sortPriority = 0; + for (const child of children) { + if (isRequestGroup(child)) { + resources.folders.push(importFolder(child, workspaceToImport._id)); + nextFolder(child._id); + } else if (isHttpRequest(child)) { + resources.httpRequests.push( + importHttpRequest(child, workspaceToImport._id, sortPriority++), + ); + } else if (isGrpcRequest(child)) { + resources.grpcRequests.push( + importGrpcRequest(child, workspaceToImport._id, sortPriority++), + ); + } + } + }; + + // Import folders + nextFolder(workspaceToImport._id); + } + + // Filter out any `null` values + resources.httpRequests = resources.httpRequests.filter(Boolean); + resources.grpcRequests = resources.grpcRequests.filter(Boolean); + resources.environments = resources.environments.filter(Boolean); + resources.workspaces = resources.workspaces.filter(Boolean); + + return { resources }; +} + +function importEnvironment(e: any, workspaceId: string): ExportResources['environments'][0] { + return { + id: convertId(e._id), + createdAt: new Date(e.created ?? Date.now()).toISOString().replace('Z', ''), + updatedAt: new Date(e.updated ?? Date.now()).toISOString().replace('Z', ''), + workspaceId: convertId(workspaceId), + model: 'environment', + name: e.name, + variables: Object.entries(e.data).map(([name, value]) => ({ + enabled: true, + name, + value: `${value}`, + })), + }; +} + +function importFolder(f: any, workspaceId: string): ExportResources['folders'][0] { + return { + id: convertId(f._id), + createdAt: new Date(f.created ?? Date.now()).toISOString().replace('Z', ''), + updatedAt: new Date(f.updated ?? Date.now()).toISOString().replace('Z', ''), + folderId: f.parentId === workspaceId ? null : convertId(f.parentId), + workspaceId: convertId(workspaceId), + model: 'folder', + name: f.name, + }; +} + +function importGrpcRequest( + r: any, + workspaceId: string, + sortPriority = 0, +): ExportResources['grpcRequests'][0] { + const parts = r.protoMethodName.split('/').filter((p: any) => p !== ''); + const service = parts[0] ?? null; + const method = parts[1] ?? null; + + return { + id: convertId(r._id), + createdAt: new Date(r.created ?? Date.now()).toISOString().replace('Z', ''), + updatedAt: new Date(r.updated ?? Date.now()).toISOString().replace('Z', ''), + workspaceId: convertId(workspaceId), + folderId: r.parentId === workspaceId ? null : convertId(r.parentId), + model: 'grpc_request', + sortPriority, + name: r.name, + url: convertSyntax(r.url), + service, + method, + message: r.body?.text ?? '', + metadata: (r.metadata ?? []) + .map((h: any) => ({ + enabled: !h.disabled, + name: h.name ?? '', + value: h.value ?? '', + })) + .filter(({ name, value }: any) => name !== '' || value !== ''), + }; +} + +function importHttpRequest( + r: any, + workspaceId: string, + sortPriority = 0, +): ExportResources['httpRequests'][0] { + let bodyType: string | null = null; + let body = {}; + if (r.body.mimeType === 'application/octet-stream') { + bodyType = 'binary'; + body = { filePath: r.body.fileName ?? '' }; + } else if (r.body?.mimeType === 'application/x-www-form-urlencoded') { + bodyType = 'application/x-www-form-urlencoded'; + body = { + form: (r.body.params ?? []).map((p: any) => ({ + enabled: !p.disabled, + name: p.name ?? '', + value: p.value ?? '', + })), + }; + } else if (r.body?.mimeType === 'multipart/form-data') { + bodyType = 'multipart/form-data'; + body = { + form: (r.body.params ?? []).map((p: any) => ({ + enabled: !p.disabled, + name: p.name ?? '', + value: p.value ?? '', + file: p.fileName ?? null, + })), + }; + } else if (r.body?.mimeType === 'application/graphql') { + bodyType = 'graphql'; + body = { text: convertSyntax(r.body.text ?? '') }; + } else if (r.body?.mimeType === 'application/json') { + bodyType = 'application/json'; + body = { text: convertSyntax(r.body.text ?? '') }; + } + + let authenticationType: string | null = null; + let authentication = {}; + if (r.authentication.type === 'bearer') { + authenticationType = 'bearer'; + authentication = { + token: convertSyntax(r.authentication.token), + }; + } else if (r.authentication.type === 'basic') { + authenticationType = 'basic'; + authentication = { + username: convertSyntax(r.authentication.username), + password: convertSyntax(r.authentication.password), + }; + } + + return { + id: convertId(r._id), + createdAt: new Date(r.created ?? Date.now()).toISOString().replace('Z', ''), + updatedAt: new Date(r.updated ?? Date.now()).toISOString().replace('Z', ''), + workspaceId: convertId(workspaceId), + folderId: r.parentId === workspaceId ? null : convertId(r.parentId), + model: 'http_request', + sortPriority, + name: r.name, + url: convertSyntax(r.url), + body, + bodyType, + authentication, + authenticationType, + method: r.method, + headers: (r.headers ?? []) + .map((h: any) => ({ + enabled: !h.disabled, + name: h.name ?? '', + value: h.value ?? '', + })) + .filter(({ name, value }: any) => name !== '' || value !== ''), + }; +} + +function parseVariables(data: Record) { + return Object.entries(data).map(([name, value]) => ({ + enabled: true, + name, + value: `${value}`, + })); +} + +function convertSyntax(variable: string): string { + if (!isJSString(variable)) return variable; + return variable.replaceAll(/{{\s*(_\.)?([^}]+)\s*}}/g, '${[$2]}'); +} + +function isWorkspace(obj: any) { + return isJSObject(obj) && obj._type === 'workspace'; +} + +function isRequestGroup(obj: any) { + return isJSObject(obj) && obj._type === 'request_group'; +} + +function isHttpRequest(obj: any) { + return isJSObject(obj) && obj._type === 'request'; +} + +function isGrpcRequest(obj: any) { + return isJSObject(obj) && obj._type === 'grpc_request'; +} + +function isEnvironment(obj: any) { + return isJSObject(obj) && obj._type === 'environment'; +} + +function isJSObject(obj: any) { + return Object.prototype.toString.call(obj) === '[object Object]'; +} + +function isJSString(obj: any) { + return Object.prototype.toString.call(obj) === '[object String]'; +} + +function convertId(id: string): string { + if (id.startsWith('GENERATE_ID::')) { + return id; + } + return `GENERATE_ID::${id}`; +} diff --git a/plugins/importer-insomnia/vite.config.js b/plugins/importer-insomnia/vite.config.js new file mode 100644 index 000000000..787b33455 --- /dev/null +++ b/plugins/importer-insomnia/vite.config.js @@ -0,0 +1,15 @@ +import { resolve } from 'path'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + fileName: 'index', + formats: ['es'], + }, + emptyOutDir: true, + sourcemap: true, + outDir: resolve(__dirname, 'build'), + }, +}); diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json new file mode 100644 index 000000000..8a024c677 --- /dev/null +++ b/plugins/importer-postman/package-lock.json @@ -0,0 +1,1505 @@ +{ + "name": "importer-postman", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "importer-postman", + "version": "0.0.1", + "devDependencies": { + "vitest": "^1.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", + "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", + "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", + "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", + "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", + "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", + "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", + "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", + "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", + "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", + "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", + "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", + "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", + "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@vitest/expect": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.4.0.tgz", + "integrity": "sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.4.0", + "@vitest/utils": "1.4.0", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.4.0.tgz", + "integrity": "sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.4.0", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.4.0.tgz", + "integrity": "sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz", + "integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", + "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "dev": true + }, + "node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true + }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mlly": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", + "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "ufo": "^1.3.2" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/pkg-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } + }, + "node_modules/postcss": { + "version": "8.4.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.36.tgz", + "integrity": "sha512-/n7eumA6ZjFHAsbX30yhHup/IMkOmlmvtEi7P+6RMYf+bGJSUHc3geH4a0NSZxAz/RJfiS9tooCTs9LAVYUZKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/rollup": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", + "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.13.0", + "@rollup/rollup-android-arm64": "4.13.0", + "@rollup/rollup-darwin-arm64": "4.13.0", + "@rollup/rollup-darwin-x64": "4.13.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", + "@rollup/rollup-linux-arm64-gnu": "4.13.0", + "@rollup/rollup-linux-arm64-musl": "4.13.0", + "@rollup/rollup-linux-riscv64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-musl": "4.13.0", + "@rollup/rollup-win32-arm64-msvc": "4.13.0", + "@rollup/rollup-win32-ia32-msvc": "4.13.0", + "@rollup/rollup-win32-x64-msvc": "4.13.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.1.0.tgz", + "integrity": "sha512-9vC2SfsJzlej6MAaMPLu8HiBSHGdRAJ9hVFYN1ibZoNkeanmDmLUcIrj6G9DGL7XMJ54AKg/G75akXl1/izTOw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz", + "integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==", + "dev": true, + "dependencies": { + "js-tokens": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/tinybench": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", + "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz", + "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ufo": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.2.tgz", + "integrity": "sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==", + "dev": true + }, + "node_modules/vite": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz", + "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==", + "dev": true, + "dependencies": { + "esbuild": "^0.19.3", + "postcss": "^8.4.35", + "rollup": "^4.2.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.4.0.tgz", + "integrity": "sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.4.0.tgz", + "integrity": "sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.4.0", + "@vitest/runner": "1.4.0", + "@vitest/snapshot": "1.4.0", + "@vitest/spy": "1.4.0", + "@vitest/utils": "1.4.0", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.2", + "vite": "^5.0.0", + "vite-node": "1.4.0", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.4.0", + "@vitest/ui": "1.4.0", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json new file mode 100644 index 000000000..73a2caf5d --- /dev/null +++ b/plugins/importer-postman/package.json @@ -0,0 +1,7 @@ +{ + "name": "importer-postman", + "version": "0.0.1", + "devDependencies": { + "vitest": "^1.4.0" + } +} diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts new file mode 100644 index 000000000..2ee5bc6fd --- /dev/null +++ b/plugins/importer-postman/src/index.ts @@ -0,0 +1,253 @@ +import { Environment, Folder, HttpRequest, Model, Workspace } from '../../../src-web/lib/models'; + +const POSTMAN_2_1_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'; +const POSTMAN_2_0_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json'; +const VALID_SCHEMAS = [POSTMAN_2_0_0_SCHEMA, POSTMAN_2_1_0_SCHEMA]; + +type AtLeast = Partial & Pick; + +interface ExportResources { + workspaces: AtLeast[]; + environments: AtLeast[]; + httpRequests: AtLeast[]; + folders: AtLeast[]; +} + +export function pluginHookImport( + _ctx: any, + contents: string, +): { resources: ExportResources } | undefined { + const root = parseJSONToRecord(contents); + if (root == null) return; + + const info = toRecord(root.info); + const isValidSchema = VALID_SCHEMAS.includes(info.schema); + if (!isValidSchema || !Array.isArray(root.item)) { + return; + } + + const globalAuth = importAuth(root.auth); + + const exportResources: ExportResources = { + workspaces: [], + environments: [], + httpRequests: [], + folders: [], + }; + + const workspace: ExportResources['workspaces'][0] = { + model: 'workspace', + id: generateId('workspace'), + name: info.name || 'Postman Import', + description: info.description || '', + variables: + root.variable?.map((v: any) => ({ + name: v.key, + value: v.value, + })) ?? [], + }; + exportResources.workspaces.push(workspace); + + const importItem = (v: Record, folderId: string | null = null) => { + if (typeof v.name === 'string' && Array.isArray(v.item)) { + const folder: ExportResources['folders'][0] = { + model: 'folder', + workspaceId: workspace.id, + id: generateId('folder'), + name: v.name, + folderId, + }; + exportResources.folders.push(folder); + for (const child of v.item) { + importItem(child, folder.id); + } + } else if (typeof v.name === 'string' && 'request' in v) { + const r = toRecord(v.request); + const bodyPatch = importBody(r.body); + const requestAuthPath = importAuth(r.auth); + const authPatch = requestAuthPath.authenticationType == null ? globalAuth : requestAuthPath; + const request: ExportResources['httpRequests'][0] = { + model: 'http_request', + id: generateId('http_request'), + workspaceId: workspace.id, + folderId, + name: v.name, + method: r.method || 'GET', + url: typeof r.url === 'string' ? r.url : toRecord(r.url).raw, + body: bodyPatch.body, + bodyType: bodyPatch.bodyType, + authentication: authPatch.authentication, + authenticationType: authPatch.authenticationType, + headers: [ + ...bodyPatch.headers, + ...authPatch.headers, + ...toArray(r.header).map((h) => { + return { + name: h.key, + value: h.value, + enabled: !h.disabled, + }; + }), + ], + }; + exportResources.httpRequests.push(request); + } else { + console.log('Unknown item', v, folderId); + } + }; + + for (const item of root.item) { + importItem(item); + } + + return { resources: convertTemplateSyntax(exportResources) }; +} + +function importAuth( + rawAuth: any, +): Pick { + const auth = toRecord(rawAuth); + if ('basic' in auth) { + return { + headers: [], + authenticationType: 'basic', + authentication: { + username: auth.basic.username || '', + password: auth.basic.password || '', + }, + }; + } else if ('bearer' in auth) { + return { + headers: [], + authenticationType: 'bearer', + authentication: { + token: auth.bearer.token || '', + }, + }; + } else { + return { headers: [], authenticationType: null, authentication: {} }; + } +} + +function importBody(rawBody: any): Pick { + const body = toRecord(rawBody); + if ('graphql' in body) { + return { + headers: [ + { + name: 'Content-Type', + value: 'application/json', + enabled: true, + }, + ], + bodyType: 'graphql', + body: { + text: JSON.stringify( + { query: body.graphql.query, variables: parseJSONToRecord(body.graphql.variables) }, + null, + 2, + ), + }, + }; + } else if ('urlencoded' in body) { + return { + headers: [ + { + name: 'Content-Type', + value: 'application/x-www-form-urlencoded', + enabled: true, + }, + ], + bodyType: 'application/x-www-form-urlencoded', + body: { + form: toArray(body.urlencoded).map((f) => ({ + enabled: !f.disabled, + name: f.key ?? '', + value: f.value ?? '', + })), + }, + }; + } else if ('formdata' in body) { + return { + headers: [ + { + name: 'Content-Type', + value: 'multipart/form-data', + enabled: true, + }, + ], + bodyType: 'multipart/form-data', + body: { + form: toArray(body.formdata).map((f) => + f.src != null + ? { + enabled: !f.disabled, + contentType: f.contentType ?? null, + name: f.key ?? '', + file: f.src ?? '', + } + : { + enabled: !f.disabled, + name: f.key ?? '', + value: f.value ?? '', + }, + ), + }, + }; + } else if ('raw' in body) { + return { + headers: [ + { + name: 'Content-Type', + value: body.options?.raw?.language === 'json' ? 'application/json' : '', + enabled: true, + }, + ], + bodyType: body.options?.raw?.language === 'json' ? 'application/json' : 'other', + body: { + text: body.raw ?? '', + }, + }; + } else { + return { headers: [], bodyType: null, body: {} }; + } +} + +function parseJSONToRecord(jsonStr: string): Record | null { + try { + return toRecord(JSON.parse(jsonStr)); + } catch (err) {} + return null; +} + +function toRecord(value: any): Record { + if (Object.prototype.toString.call(value) === '[object Object]') return value; + else return {}; +} + +function toArray(value: any): any[] { + if (Object.prototype.toString.call(value) === '[object Array]') return value; + else return []; +} + +/** Recursively render all nested object properties */ +function convertTemplateSyntax(obj: T): T { + if (typeof obj === 'string') { + return obj.replace(/{{\s*(_\.)?([^}]+)\s*}}/g, '${[$2]}') as T; + } else if (Array.isArray(obj) && obj != null) { + return obj.map(convertTemplateSyntax) as T; + } else if (typeof obj === 'object' && obj != null) { + return Object.fromEntries( + Object.entries(obj).map(([k, v]) => [k, convertTemplateSyntax(v)]), + ) as T; + } else { + return obj; + } +} + +const idCount: Partial> = {}; + +function generateId(model: Model['model']): string { + idCount[model] = (idCount[model] ?? -1) + 1; + return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`; +} diff --git a/plugins/importer-postman/tests/fixtures/nested.json b/plugins/importer-postman/tests/fixtures/nested.json new file mode 100644 index 000000000..0061656ea --- /dev/null +++ b/plugins/importer-postman/tests/fixtures/nested.json @@ -0,0 +1,38 @@ +{ + "info": { + "_postman_id": "9e6dfada-256c-49ea-a38f-7d1b05b7ca2d", + "name": "New Collection", + "schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json", + "_exporter_id": "18798" + }, + "item": [ + { + "name": "Top Folder", + "item": [ + { + "name": "Nested Folder", + "item": [ + { + "name": "Request 1", + "request": { + "method": "GET" + } + } + ] + }, + { + "name": "Request 2", + "request": { + "method": "GET" + } + } + ] + }, + { + "name": "Request 3", + "request": { + "method": "GET" + } + } + ] +} diff --git a/plugins/importer-postman/tests/index.test.ts b/plugins/importer-postman/tests/index.test.ts new file mode 100644 index 000000000..108521672 --- /dev/null +++ b/plugins/importer-postman/tests/index.test.ts @@ -0,0 +1,91 @@ +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; +import { Model } from '../../../src-web/lib/models'; +import { pluginHookImport } from '../src'; + +let originalRandom = Math.random; + +describe('importer-postman', () => { + beforeEach(() => { + let i = 0; + // Psuedo-random number generator to ensure consistent ID generation + Math.random = vi.fn(() => ((i++ * 1000) % 133) / 100); + }); + + afterEach(() => { + Math.random = originalRandom; + }); + + const p = path.join(__dirname, 'fixtures'); + const fixtures = fs.readdirSync(p); + + for (const fixture of fixtures) { + test('Imports ' + fixture, () => { + const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); + const imported = pluginHookImport({}, contents); + const folder0 = newId('folder'); + const folder1 = newId('folder'); + expect(imported).toEqual({ + resources: expect.objectContaining({ + workspaces: [ + expect.objectContaining({ + id: newId('workspace'), + model: 'workspace', + name: 'New Collection', + }), + ], + folders: expect.arrayContaining([ + expect.objectContaining({ + id: folder0, + model: 'folder', + workspaceId: existingId('workspace'), + name: 'Top Folder', + }), + expect.objectContaining({ + folderId: folder0, + id: folder1, + model: 'folder', + workspaceId: existingId('workspace'), + name: 'Nested Folder', + }), + ]), + httpRequests: expect.arrayContaining([ + expect.objectContaining({ + id: newId('http_request'), + model: 'http_request', + name: 'Request 1', + workspaceId: existingId('workspace'), + folderId: folder1, + }), + expect.objectContaining({ + id: newId('http_request'), + model: 'http_request', + name: 'Request 2', + workspaceId: existingId('workspace'), + folderId: folder0, + }), + expect.objectContaining({ + id: newId('http_request'), + model: 'http_request', + name: 'Request 3', + workspaceId: existingId('workspace'), + folderId: null, + }), + ]), + }), + }); + }); + } +}); + +const idCount: Partial> = {}; + +function newId(model: Model['model']): string { + idCount[model] = (idCount[model] ?? -1) + 1; + return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`; +} + +function existingId(model: Model['model']): string { + return `GENERATE_ID::${model.toUpperCase()}_${idCount[model] ?? 0}`; +} diff --git a/plugins/importer-postman/tsconfig.json b/plugins/importer-postman/tsconfig.json new file mode 100644 index 000000000..20f016b69 --- /dev/null +++ b/plugins/importer-postman/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": [ + "ESNext", + ], + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": [ + "./src" + ] +} diff --git a/plugins/importer-postman/vite.config.js b/plugins/importer-postman/vite.config.js new file mode 100644 index 000000000..787b33455 --- /dev/null +++ b/plugins/importer-postman/vite.config.js @@ -0,0 +1,15 @@ +import { resolve } from 'path'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + fileName: 'index', + formats: ['es'], + }, + emptyOutDir: true, + sourcemap: true, + outDir: resolve(__dirname, 'build'), + }, +}); diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json new file mode 100644 index 000000000..ed05c44a9 --- /dev/null +++ b/plugins/importer-yaak/package-lock.json @@ -0,0 +1,12 @@ +{ + "name": "importer-yaak", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "importer-yaak", + "version": "0.0.1" + } + } +} diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json new file mode 100644 index 000000000..eca406209 --- /dev/null +++ b/plugins/importer-yaak/package.json @@ -0,0 +1,4 @@ +{ + "name": "importer-yaak", + "version": "0.0.1" +} diff --git a/plugins/importer-yaak/src/index.ts b/plugins/importer-yaak/src/index.ts new file mode 100644 index 000000000..f50a13fdd --- /dev/null +++ b/plugins/importer-yaak/src/index.ts @@ -0,0 +1,29 @@ +export function pluginHookImport(ctx: any, contents: string) { + let parsed; + try { + parsed = JSON.parse(contents); + } catch (err) { + return undefined; + } + + if (!isJSObject(parsed)) { + return undefined; + } + + const isYaakExport = 'yaakSchema' in parsed; + if (!isYaakExport) { + return; + } + + // Migrate v1 to v2 -- changes requests to httpRequests + if ('requests' in parsed.resources) { + parsed.resources.httpRequests = parsed.resources.requests; + delete parsed.resources['requests']; + } + + return { resources: parsed.resources }; // Should already be in the correct format +} + +export function isJSObject(obj: any) { + return Object.prototype.toString.call(obj) === '[object Object]'; +} diff --git a/plugins/importer-yaak/tests/index.test.ts b/plugins/importer-yaak/tests/index.test.ts new file mode 100644 index 000000000..38e44133a --- /dev/null +++ b/plugins/importer-yaak/tests/index.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, test } from 'vitest'; +import { pluginHookImport } from '../src'; + +const ctx = {}; + +describe('importer-yaak', () => { + test('Skips invalid imports', () => { + expect(pluginHookImport(ctx, 'not JSON')).toBeUndefined(); + expect(pluginHookImport(ctx, '[]')).toBeUndefined(); + expect(pluginHookImport(ctx, JSON.stringify({ resources: {} }))).toBeUndefined(); + }); + + test('converts schema 1 to 2', () => { + const imported = pluginHookImport( + ctx, + JSON.stringify({ + yaakSchema: 1, + resources: { + requests: [], + }, + }), + ); + + expect(imported).toEqual( + expect.objectContaining({ + resources: { + httpRequests: [], + }, + }), + ); + }); +}); diff --git a/plugins/importer-yaak/vite.config.js b/plugins/importer-yaak/vite.config.js new file mode 100644 index 000000000..787b33455 --- /dev/null +++ b/plugins/importer-yaak/vite.config.js @@ -0,0 +1,15 @@ +import { resolve } from 'path'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + fileName: 'index', + formats: ['es'], + }, + emptyOutDir: true, + sourcemap: true, + outDir: resolve(__dirname, 'build'), + }, +}); From 47b8c4dd6b74a5f93352f732de195b0b104988f8 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 18 Jul 2024 16:37:20 -0700 Subject: [PATCH 003/996] A few tweaks --- package.json | 8 + plugins/exporter-curl/package-lock.json | 230 +++--- plugins/exporter-curl/package.json | 6 + plugins/exporter-curl/vite.config.js | 15 - plugins/filter-jsonpath/package-lock.json | 818 ++++++++++++++++++- plugins/filter-jsonpath/package.json | 8 +- plugins/filter-jsonpath/vite.config.js | 15 - plugins/filter-xpath/package-lock.json | 815 +++++++++++++++++++ plugins/filter-xpath/package.json | 8 + plugins/filter-xpath/vite.config.js | 15 - plugins/importer-curl/package-lock.json | 229 +++--- plugins/importer-curl/package.json | 6 + plugins/importer-curl/vite.config.js | 15 - plugins/importer-insomnia/package-lock.json | 818 +++++++++++++++++++ plugins/importer-insomnia/package.json | 8 + plugins/importer-insomnia/vite.config.js | 15 - plugins/importer-postman/package-lock.json | 247 +++--- plugins/importer-postman/package.json | 6 + plugins/importer-postman/src/index.ts | 2 +- plugins/importer-postman/tsconfig.json | 23 - plugins/importer-postman/vite.config.js | 15 - plugins/importer-yaak/package-lock.json | 820 +++++++++++++++++++- plugins/importer-yaak/package.json | 10 +- plugins/importer-yaak/vite.config.js | 15 - scripts/build-plugins.cjs | 20 + tsconfig.json | 26 + types/models.ts | 213 +++++ 27 files changed, 3987 insertions(+), 439 deletions(-) create mode 100644 package.json delete mode 100644 plugins/exporter-curl/vite.config.js delete mode 100644 plugins/filter-jsonpath/vite.config.js delete mode 100644 plugins/filter-xpath/vite.config.js delete mode 100644 plugins/importer-curl/vite.config.js delete mode 100644 plugins/importer-insomnia/vite.config.js delete mode 100644 plugins/importer-postman/tsconfig.json delete mode 100644 plugins/importer-postman/vite.config.js delete mode 100644 plugins/importer-yaak/vite.config.js create mode 100644 scripts/build-plugins.cjs create mode 100644 tsconfig.json create mode 100644 types/models.ts diff --git a/package.json b/package.json new file mode 100644 index 000000000..eadcd8ccd --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "name": "@yaakapp/plugins", + "repository": "https://github.com/yaakapp/plugins", + "private": true, + "scripts": { + "build": "node scripts/build-plugins.cjs" + } +} diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json index c8ee5b8a2..f6d3211cf 100644 --- a/plugins/exporter-curl/package-lock.json +++ b/plugins/exporter-curl/package-lock.json @@ -8,13 +8,17 @@ "name": "exporter-curl", "version": "0.0.1", "devDependencies": { + "@types/node": "^20.14.9", + "esbuild": "^0.21.5", + "typescript": "^5.5.2", + "vite": "^5.3.2", "vitest": "^1.4.0" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -28,9 +32,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -44,9 +48,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -60,9 +64,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -76,9 +80,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -92,9 +96,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -108,9 +112,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -124,9 +128,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -140,9 +144,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -156,9 +160,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -172,9 +176,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -188,9 +192,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -204,9 +208,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -220,9 +224,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -236,9 +240,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -252,9 +256,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -268,9 +272,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -284,9 +288,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -300,9 +304,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -316,9 +320,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -332,9 +336,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -348,9 +352,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -364,9 +368,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -617,6 +621,15 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@vitest/expect": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", @@ -826,9 +839,9 @@ } }, "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "bin": { @@ -838,29 +851,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/estree-walker": { @@ -1349,19 +1362,38 @@ "node": ">=4" } }, + "node_modules/typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/ufo": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", "dev": true }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/vite": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", - "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", "dev": true, "dependencies": { - "esbuild": "^0.20.1", + "esbuild": "^0.21.3", "postcss": "^8.4.38", "rollup": "^4.13.0" }, diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index 4674e1a0e..6fb28d56e 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -1,7 +1,13 @@ { "name": "exporter-curl", "version": "0.0.1", + "scripts": { + "build": "yaak-cli ./src/index.js" + }, "devDependencies": { + "@types/node": "^20.14.9", + "esbuild": "^0.21.5", + "typescript": "^5.5.2", "vitest": "^1.4.0" } } diff --git a/plugins/exporter-curl/vite.config.js b/plugins/exporter-curl/vite.config.js deleted file mode 100644 index 787b33455..000000000 --- a/plugins/exporter-curl/vite.config.js +++ /dev/null @@ -1,15 +0,0 @@ -import { resolve } from 'path'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - build: { - lib: { - entry: resolve(__dirname, 'src/index.ts'), - fileName: 'index', - formats: ['es'], - }, - emptyOutDir: true, - sourcemap: true, - outDir: resolve(__dirname, 'build'), - }, -}); diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index 4bacbcc84..bd740bf69 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -11,20 +11,652 @@ "jsonpath": "^1.1.1" }, "devDependencies": { - "@types/jsonpath": "^0.2.4" + "@types/jsonpath": "^0.2.4", + "@types/node": "^20.14.9", + "typescript": "^5.5.2", + "vite": "^5.3.2" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/jsonpath": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.4.tgz", "integrity": "sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA==", "dev": true }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, "node_modules/escodegen": { "version": "1.14.3", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", @@ -91,6 +723,20 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/jsonpath": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", @@ -113,6 +759,24 @@ "node": ">= 0.8.0" } }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -129,6 +793,40 @@ "node": ">= 0.8.0" } }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -137,6 +835,41 @@ "node": ">= 0.8.0" } }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -146,6 +879,15 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/static-eval": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", @@ -165,11 +907,85 @@ "node": ">= 0.8.0" } }, + "node_modules/typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/underscore": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/vite": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index ce608c093..c746f9236 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -1,10 +1,16 @@ { "name": "filter-jsonpath", "version": "0.0.1", + "scripts": { + "build": "yaak-cli src/index.ts" + }, "dependencies": { "jsonpath": "^1.1.1" }, "devDependencies": { - "@types/jsonpath": "^0.2.4" + "@types/jsonpath": "^0.2.4", + "@types/node": "^20.14.9", + "esbuild": "^0.21.5", + "typescript": "^5.5.2" } } diff --git a/plugins/filter-jsonpath/vite.config.js b/plugins/filter-jsonpath/vite.config.js deleted file mode 100644 index 787b33455..000000000 --- a/plugins/filter-jsonpath/vite.config.js +++ /dev/null @@ -1,15 +0,0 @@ -import { resolve } from 'path'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - build: { - lib: { - entry: resolve(__dirname, 'src/index.ts'), - fileName: 'index', - formats: ['es'], - }, - emptyOutDir: true, - sourcemap: true, - outDir: resolve(__dirname, 'build'), - }, -}); diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json index 9fb40cd46..eaae4b96d 100644 --- a/plugins/filter-xpath/package-lock.json +++ b/plugins/filter-xpath/package-lock.json @@ -8,8 +8,603 @@ "name": "filter-xpath", "version": "0.0.1", "dependencies": { + "@types/node": "^20.14.9", "@xmldom/xmldom": "^0.8.10", + "typescript": "^5.5.2", "xpath": "^0.0.34" + }, + "devDependencies": { + "vite": "^5.3.2" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dependencies": { + "undici-types": "~5.26.4" } }, "node_modules/@xmldom/xmldom": { @@ -20,6 +615,226 @@ "node": ">=10.0.0" } }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/vite": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, "node_modules/xpath": { "version": "0.0.34", "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index 897faa3d4..e360b54f8 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -1,8 +1,16 @@ { "name": "filter-xpath", "version": "0.0.1", + "scripts": { + "build": "yaak-cli ./src/index.js" + }, "dependencies": { + "@types/node": "^20.14.9", "@xmldom/xmldom": "^0.8.10", + "typescript": "^5.5.2", "xpath": "^0.0.34" + }, + "devDependencies": { + "esbuild": "^0.21.5" } } diff --git a/plugins/filter-xpath/vite.config.js b/plugins/filter-xpath/vite.config.js deleted file mode 100644 index 787b33455..000000000 --- a/plugins/filter-xpath/vite.config.js +++ /dev/null @@ -1,15 +0,0 @@ -import { resolve } from 'path'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - build: { - lib: { - entry: resolve(__dirname, 'src/index.ts'), - fileName: 'index', - formats: ['es'], - }, - emptyOutDir: true, - sourcemap: true, - outDir: resolve(__dirname, 'build'), - }, -}); diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json index 2846dda89..468885344 100644 --- a/plugins/importer-curl/package-lock.json +++ b/plugins/importer-curl/package-lock.json @@ -11,14 +11,17 @@ "shell-quote": "^1.8.1" }, "devDependencies": { + "@types/node": "^20.14.9", "@types/shell-quote": "^1.7.5", + "typescript": "^5.5.2", + "vite": "^5.3.2", "vitest": "^1.4.0" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -32,9 +35,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -48,9 +51,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -64,9 +67,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -80,9 +83,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -96,9 +99,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -112,9 +115,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -128,9 +131,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -144,9 +147,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -160,9 +163,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -176,9 +179,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -192,9 +195,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -208,9 +211,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -224,9 +227,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -240,9 +243,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -256,9 +259,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -272,9 +275,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -288,9 +291,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -304,9 +307,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -320,9 +323,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -336,9 +339,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -352,9 +355,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -368,9 +371,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -621,6 +624,15 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@types/shell-quote": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/@types/shell-quote/-/shell-quote-1.7.5.tgz", @@ -836,9 +848,9 @@ } }, "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "bin": { @@ -848,29 +860,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/estree-walker": { @@ -1367,19 +1379,38 @@ "node": ">=4" } }, + "node_modules/typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/ufo": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", "dev": true }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/vite": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", - "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", "dev": true, "dependencies": { - "esbuild": "^0.20.1", + "esbuild": "^0.21.3", "postcss": "^8.4.38", "rollup": "^4.13.0" }, diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index 989b2d662..6aa49c01e 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -1,11 +1,17 @@ { "name": "importer-curl", "version": "0.0.1", + "scripts": { + "build": "yaak-cli ./src/index.js" + }, "dependencies": { "shell-quote": "^1.8.1" }, "devDependencies": { + "@types/node": "^20.14.9", "@types/shell-quote": "^1.7.5", + "esbuild": "^0.21.5", + "typescript": "^5.5.2", "vitest": "^1.4.0" } } diff --git a/plugins/importer-curl/vite.config.js b/plugins/importer-curl/vite.config.js deleted file mode 100644 index 787b33455..000000000 --- a/plugins/importer-curl/vite.config.js +++ /dev/null @@ -1,15 +0,0 @@ -import { resolve } from 'path'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - build: { - lib: { - entry: resolve(__dirname, 'src/index.ts'), - fileName: 'index', - formats: ['es'], - }, - emptyOutDir: true, - sourcemap: true, - outDir: resolve(__dirname, 'build'), - }, -}); diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json index a7dd6a64c..80ec94825 100644 --- a/plugins/importer-insomnia/package-lock.json +++ b/plugins/importer-insomnia/package-lock.json @@ -9,6 +9,824 @@ "version": "0.0.1", "dependencies": { "yaml": "^2.4.2" + }, + "devDependencies": { + "@types/node": "^20.14.9", + "typescript": "^5.5.2", + "vite": "^5.3.2" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/vite": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } } }, "node_modules/yaml": { diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 7432d4960..05907186e 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -1,7 +1,15 @@ { "name": "importer-insomnia", "version": "0.0.1", + "scripts": { + "build": "yaak-cli ./src/index.js" + }, "dependencies": { "yaml": "^2.4.2" + }, + "devDependencies": { + "@types/node": "^20.14.9", + "esbuild": "^0.21.5", + "typescript": "^5.5.2" } } diff --git a/plugins/importer-insomnia/vite.config.js b/plugins/importer-insomnia/vite.config.js deleted file mode 100644 index 787b33455..000000000 --- a/plugins/importer-insomnia/vite.config.js +++ /dev/null @@ -1,15 +0,0 @@ -import { resolve } from 'path'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - build: { - lib: { - entry: resolve(__dirname, 'src/index.ts'), - fileName: 'index', - formats: ['es'], - }, - emptyOutDir: true, - sourcemap: true, - outDir: resolve(__dirname, 'build'), - }, -}); diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json index 8a024c677..ff8ae5359 100644 --- a/plugins/importer-postman/package-lock.json +++ b/plugins/importer-postman/package-lock.json @@ -8,13 +8,16 @@ "name": "importer-postman", "version": "0.0.1", "devDependencies": { + "@types/node": "^20.14.9", + "typescript": "^5.5.2", + "vite": "^5.3.2", "vitest": "^1.4.0" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -28,9 +31,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -44,9 +47,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -60,9 +63,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -76,9 +79,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -92,9 +95,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -108,9 +111,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -124,9 +127,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -140,9 +143,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -156,9 +159,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -172,9 +175,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -188,9 +191,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -204,9 +207,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -220,9 +223,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -236,9 +239,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -252,9 +255,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -268,9 +271,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -284,9 +287,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -300,9 +303,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -316,9 +319,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -332,9 +335,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -348,9 +351,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -364,9 +367,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -578,6 +581,15 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@vitest/expect": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.4.0.tgz", @@ -781,9 +793,9 @@ } }, "node_modules/esbuild": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "bin": { @@ -793,29 +805,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/estree-walker": { @@ -1114,9 +1126,9 @@ } }, "node_modules/postcss": { - "version": "8.4.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.36.tgz", - "integrity": "sha512-/n7eumA6ZjFHAsbX30yhHup/IMkOmlmvtEi7P+6RMYf+bGJSUHc3geH4a0NSZxAz/RJfiS9tooCTs9LAVYUZKw==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -1135,7 +1147,7 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.1.0" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -1233,9 +1245,9 @@ } }, "node_modules/source-map-js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.1.0.tgz", - "integrity": "sha512-9vC2SfsJzlej6MAaMPLu8HiBSHGdRAJ9hVFYN1ibZoNkeanmDmLUcIrj6G9DGL7XMJ54AKg/G75akXl1/izTOw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -1310,21 +1322,40 @@ "node": ">=4" } }, + "node_modules/typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/ufo": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.2.tgz", "integrity": "sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==", "dev": true }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/vite": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz", - "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", "dev": true, "dependencies": { - "esbuild": "^0.19.3", - "postcss": "^8.4.35", - "rollup": "^4.2.0" + "esbuild": "^0.21.3", + "postcss": "^8.4.38", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 73a2caf5d..126ba8b4b 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -1,7 +1,13 @@ { "name": "importer-postman", "version": "0.0.1", + "scripts": { + "build": "yaak-cli ./src/index.js" + }, "devDependencies": { + "@types/node": "^20.14.9", + "esbuild": "^0.21.5", + "typescript": "^5.5.2", "vitest": "^1.4.0" } } diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts index 2ee5bc6fd..d4aa2755f 100644 --- a/plugins/importer-postman/src/index.ts +++ b/plugins/importer-postman/src/index.ts @@ -1,4 +1,4 @@ -import { Environment, Folder, HttpRequest, Model, Workspace } from '../../../src-web/lib/models'; +import { Environment, Folder, HttpRequest, Model, Workspace } from '../../../types/models'; const POSTMAN_2_1_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'; const POSTMAN_2_0_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json'; diff --git a/plugins/importer-postman/tsconfig.json b/plugins/importer-postman/tsconfig.json deleted file mode 100644 index 20f016b69..000000000 --- a/plugins/importer-postman/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "module": "ESNext", - "lib": [ - "ESNext", - ], - "skipLibCheck": true, - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - }, - "include": [ - "./src" - ] -} diff --git a/plugins/importer-postman/vite.config.js b/plugins/importer-postman/vite.config.js deleted file mode 100644 index 787b33455..000000000 --- a/plugins/importer-postman/vite.config.js +++ /dev/null @@ -1,15 +0,0 @@ -import { resolve } from 'path'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - build: { - lib: { - entry: resolve(__dirname, 'src/index.ts'), - fileName: 'index', - formats: ['es'], - }, - emptyOutDir: true, - sourcemap: true, - outDir: resolve(__dirname, 'build'), - }, -}); diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json index ed05c44a9..fccd4265a 100644 --- a/plugins/importer-yaak/package-lock.json +++ b/plugins/importer-yaak/package-lock.json @@ -6,7 +6,825 @@ "packages": { "": { "name": "importer-yaak", - "version": "0.0.1" + "version": "0.0.1", + "devDependencies": { + "@types/node": "^20.14.9", + "typescript": "^5.5.2", + "vite": "^5.3.2" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/vite": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } } } } diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index eca406209..718269174 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -1,4 +1,12 @@ { "name": "importer-yaak", - "version": "0.0.1" + "version": "0.0.1", + "scripts": { + "build": "yaak-cli ./src/index.js" + }, + "devDependencies": { + "@types/node": "^20.14.9", + "esbuild": "^0.21.5", + "typescript": "^5.5.2" + } } diff --git a/plugins/importer-yaak/vite.config.js b/plugins/importer-yaak/vite.config.js deleted file mode 100644 index 787b33455..000000000 --- a/plugins/importer-yaak/vite.config.js +++ /dev/null @@ -1,15 +0,0 @@ -import { resolve } from 'path'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - build: { - lib: { - entry: resolve(__dirname, 'src/index.ts'), - fileName: 'index', - formats: ['es'], - }, - emptyOutDir: true, - sourcemap: true, - outDir: resolve(__dirname, 'build'), - }, -}); diff --git a/scripts/build-plugins.cjs b/scripts/build-plugins.cjs new file mode 100644 index 000000000..3d014301f --- /dev/null +++ b/scripts/build-plugins.cjs @@ -0,0 +1,20 @@ +const {readdirSync, readFileSync} = require('node:fs'); +const {execSync} = require('node:child_process'); +const path = require('node:path'); + +async function main() { + console.log('Building plugins'); + + const pluginsDir = path.join(__dirname, '../plugins'); + const pluginNames = readdirSync(pluginsDir); + + for (const dir of pluginNames) { + const pluginDir = path.join(pluginsDir, dir); + const pkg = JSON.parse(readFileSync(path.join(pluginDir, 'package.json'), 'utf8')); + + console.log('Building plugin', pkg.name, pluginDir); + execSync(`npm run build`, {cwd: pluginDir}); + } +} + +main().catch(err => console.log('Failed', err)); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..db795350b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "include": [ + "types", + "plugins" + ], + "exclude": ["plugins/*/node_modules"], + "compilerOptions": { + "target": "es2021", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "useDefineForClassFields": true, + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "noUncheckedIndexedAccess": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + } +} diff --git a/types/models.ts b/types/models.ts new file mode 100644 index 000000000..fb8d804c7 --- /dev/null +++ b/types/models.ts @@ -0,0 +1,213 @@ +export type Model = + | Settings + | Workspace + | Folder + | GrpcConnection + | GrpcRequest + | GrpcEvent + | HttpRequest + | HttpResponse + | KeyValue + | Environment + | CookieJar; + +export interface BaseModel { + readonly id: string; + readonly createdAt: string; + readonly updatedAt: string; +} + +export interface Settings extends BaseModel { + readonly model: 'settings'; + theme: string; + appearance: string; + themeLight: string; + themeDark: string; + updateChannel: string; + interfaceFontSize: number; + interfaceScale: number; + editorFontSize: number; + editorSoftWrap: boolean; + openWorkspaceNewWindow: boolean | null; +} + +export interface Workspace extends BaseModel { + readonly model: 'workspace'; + name: string; + description: string; + variables: EnvironmentVariable[]; + settingValidateCertificates: boolean; + settingFollowRedirects: boolean; + settingRequestTimeout: number; +} + +export interface CookieJar extends BaseModel { + readonly model: 'cookie_jar'; + workspaceId: string; + name: string; + cookies: Cookie[]; +} + +export interface Cookie { + raw_cookie: string; + domain: { HostOnly: string } | { Suffix: string } | 'NotPresent' | 'Empty'; + expires: { AtUtc: string } | 'SessionEnd'; + path: [string, boolean]; +} + +export function cookieDomain(cookie: Cookie): string { + if (cookie.domain === 'NotPresent' || cookie.domain === 'Empty') { + return 'n/a'; + } + if ('HostOnly' in cookie.domain) { + return cookie.domain.HostOnly; + } + if ('Suffix' in cookie.domain) { + return cookie.domain.Suffix; + } + return 'unknown'; +} + +export interface EnvironmentVariable { + name: string; + value: string; + enabled?: boolean; +} + +export interface Folder extends BaseModel { + readonly workspaceId: string; + readonly model: 'folder'; + folderId: string | null; + sortPriority: number; + name: string; +} + +export interface Environment extends BaseModel { + readonly workspaceId: string; + readonly model: 'environment'; + name: string; + variables: EnvironmentVariable[]; +} + +export interface HttpHeader { + name: string; + value: string; + enabled?: boolean; +} + +export interface HttpUrlParameter { + name: string; + value: string; + enabled?: boolean; +} + +export interface GrpcMetadataEntry { + name: string; + value: string; + enabled?: boolean; +} + +export interface GrpcRequest extends BaseModel { + readonly workspaceId: string; + readonly model: 'grpc_request'; + folderId: string | null; + sortPriority: number; + name: string; + url: string; + service: string | null; + method: string | null; + message: string; + authentication: Record; + authenticationType: string | null; + metadata: GrpcMetadataEntry[]; +} + +export interface GrpcEvent extends BaseModel { + readonly workspaceId: string; + readonly requestId: string; + readonly connectionId: string; + readonly model: 'grpc_event'; + content: string; + status: number | null; + error: string | null; + eventType: + | 'info' + | 'error' + | 'client_message' + | 'server_message' + | 'connection_start' + | 'connection_end'; + metadata: Record; +} + +export interface GrpcConnection extends BaseModel { + readonly workspaceId: string; + readonly requestId: string; + readonly model: 'grpc_connection'; + service: string; + method: string; + elapsed: number; + elapsedConnection: number; + status: number; + url: string; + error: string | null; + trailers: Record; +} + +export interface HttpRequest extends BaseModel { + readonly workspaceId: string; + readonly model: 'http_request'; + folderId: string | null; + sortPriority: number; + name: string; + url: string; + urlParameters: HttpUrlParameter[]; + body: Record; + bodyType: string | null; + authentication: Record; + authenticationType: string | null; + method: string; + headers: HttpHeader[]; +} + +export interface KeyValue extends Omit { + readonly model: 'key_value'; + readonly key: string; + readonly namespace: string; + value: string; +} + +export interface HttpResponse extends BaseModel { + readonly workspaceId: string; + readonly model: 'http_response'; + readonly requestId: string; + readonly bodyPath: string | null; + readonly contentLength: number | null; + readonly error: string; + readonly status: number; + readonly elapsed: number; + readonly elapsedHeaders: number; + readonly statusReason: string; + readonly version: string; + readonly remoteAddr: string; + readonly url: string; + readonly headers: HttpHeader[]; +} + +export function isResponseLoading(response: HttpResponse | GrpcConnection): boolean { + return response.elapsed === 0; +} + +export function modelsEq(a: Model, b: Model) { + if (a.model === 'key_value' && b.model === 'key_value') { + return a.key === b.key && a.namespace === b.namespace; + } + if ('id' in a && 'id' in b) { + return a.id === b.id; + } + return false; +} + +export function getContentTypeHeader(headers: HttpHeader[]): string | null { + return headers.find((h) => h.name.toLowerCase() === 'content-type')?.value ?? null; +} From 7625727324cfa37caaa616dcf49298580b9ed9d0 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 19 Jul 2024 11:10:35 -0700 Subject: [PATCH 004/996] package-lock --- package-lock.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..2ea0cad32 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,10 @@ +{ + "name": "@yaakapp/plugins", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@yaakapp/plugins" + } + } +} From 77825ee89e22bb42f2c83e086b2e6eb3ab568eea Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 19 Jul 2024 14:39:10 -0700 Subject: [PATCH 005/996] Update plugins --- plugins/exporter-curl/package.json | 2 +- plugins/filter-jsonpath/package.json | 2 +- plugins/filter-xpath/package.json | 2 +- plugins/importer-curl/package.json | 2 +- plugins/importer-insomnia/package.json | 2 +- plugins/importer-postman/package.json | 2 +- plugins/importer-yaak/package.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index 6fb28d56e..f3d848687 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -2,7 +2,7 @@ "name": "exporter-curl", "version": "0.0.1", "scripts": { - "build": "yaak-cli ./src/index.js" + "build": "yaakcli ./src/index.js" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index c746f9236..3e0397ea4 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -2,7 +2,7 @@ "name": "filter-jsonpath", "version": "0.0.1", "scripts": { - "build": "yaak-cli src/index.ts" + "build": "yaakcli src/index.ts" }, "dependencies": { "jsonpath": "^1.1.1" diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index e360b54f8..82c910fad 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -2,7 +2,7 @@ "name": "filter-xpath", "version": "0.0.1", "scripts": { - "build": "yaak-cli ./src/index.js" + "build": "yaakcli ./src/index.js" }, "dependencies": { "@types/node": "^20.14.9", diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index 6aa49c01e..ceef1e0c6 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -2,7 +2,7 @@ "name": "importer-curl", "version": "0.0.1", "scripts": { - "build": "yaak-cli ./src/index.js" + "build": "yaakcli ./src/index.js" }, "dependencies": { "shell-quote": "^1.8.1" diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 05907186e..55a646e3a 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -2,7 +2,7 @@ "name": "importer-insomnia", "version": "0.0.1", "scripts": { - "build": "yaak-cli ./src/index.js" + "build": "yaakcli ./src/index.js" }, "dependencies": { "yaml": "^2.4.2" diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 126ba8b4b..3265cadf5 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -2,7 +2,7 @@ "name": "importer-postman", "version": "0.0.1", "scripts": { - "build": "yaak-cli ./src/index.js" + "build": "yaakcli ./src/index.js" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index 718269174..b8e4bc1df 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -2,7 +2,7 @@ "name": "importer-yaak", "version": "0.0.1", "scripts": { - "build": "yaak-cli ./src/index.js" + "build": "yaakcli ./src/index.js" }, "devDependencies": { "@types/node": "^20.14.9", From cc3cb6d14f1f7d11d4319e0132bfe8f20eef5554 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 19 Jul 2024 14:41:59 -0700 Subject: [PATCH 006/996] Add `npm ci` to plugin builds --- scripts/build-plugins.cjs | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/build-plugins.cjs b/scripts/build-plugins.cjs index 3d014301f..fb184ef24 100644 --- a/scripts/build-plugins.cjs +++ b/scripts/build-plugins.cjs @@ -13,6 +13,7 @@ async function main() { const pkg = JSON.parse(readFileSync(path.join(pluginDir, 'package.json'), 'utf8')); console.log('Building plugin', pkg.name, pluginDir); + execSync(`npm ci`, {cwd: pluginDir}); execSync(`npm run build`, {cwd: pluginDir}); } } From 8efc38b3eb8787832a693865bce60fa210cb4a34 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 19 Jul 2024 15:06:09 -0700 Subject: [PATCH 007/996] Vendor yaak-cli --- package-lock.json | 188 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 3 + 2 files changed, 190 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 2ea0cad32..e2325ae2b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,7 +4,193 @@ "requires": true, "packages": { "": { - "name": "@yaakapp/plugins" + "name": "@yaakapp/plugins", + "devDependencies": { + "@yaakapp/cli": "^0.0.8" + } + }, + "node_modules/@yaakapp/cli": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.8.tgz", + "integrity": "sha512-koE6zSDJj37blUIS9+W2VSeSK+UBQ4C80To7MdshorrTRjnTesNONF2GlDEbQrMnWC7PHdAhcHki/O52clxyeA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "golang-npm": "^0.0.6" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/golang-npm": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/golang-npm/-/golang-npm-0.0.6.tgz", + "integrity": "sha512-7vDCGw1xcdXDLKF+KWdtAvAW3XAxsQsn3rHYfBYSVR5xVgWkGpgCyfUJCapdtYAu3Hnwu3bkIfsOj4MvxpX4jw==", + "dev": true, + "dependencies": { + "mkdirp": "^3.0.1", + "node-fetch": "^2.7.0", + "tar": "^6.2.1" + }, + "bin": { + "golang-npm": "bin/index.js" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } } diff --git a/package.json b/package.json index eadcd8ccd..cec2edd44 100644 --- a/package.json +++ b/package.json @@ -4,5 +4,8 @@ "private": true, "scripts": { "build": "node scripts/build-plugins.cjs" + }, + "devDependencies": { + "@yaakapp/cli": "^0.0.8" } } From 324e7da2823987a1ef3ece59a769b1d7a306dac6 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 19 Jul 2024 15:40:46 -0700 Subject: [PATCH 008/996] Proper exit code --- scripts/build-plugins.cjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/build-plugins.cjs b/scripts/build-plugins.cjs index fb184ef24..2e617472c 100644 --- a/scripts/build-plugins.cjs +++ b/scripts/build-plugins.cjs @@ -18,4 +18,7 @@ async function main() { } } -main().catch(err => console.log('Failed', err)); +main().catch(err => { + console.log('Failed', err); + process.exit(1); +}); From 5ba18af021c9cc32618db695c6f19b623505c6b2 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 19 Jul 2024 16:14:13 -0700 Subject: [PATCH 009/996] Remove Yaak CLI npm package --- package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/package.json b/package.json index cec2edd44..eadcd8ccd 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,5 @@ "private": true, "scripts": { "build": "node scripts/build-plugins.cjs" - }, - "devDependencies": { - "@yaakapp/cli": "^0.0.8" } } From 4cbfe50fce69033c972903c34c37b43890c31c17 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 21 Jul 2024 16:04:29 -0700 Subject: [PATCH 010/996] Tweak --- package-lock.json | 188 +---------------------------- plugins/importer-yaak/src/index.ts | 2 +- 2 files changed, 2 insertions(+), 188 deletions(-) diff --git a/package-lock.json b/package-lock.json index e2325ae2b..2ea0cad32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,193 +4,7 @@ "requires": true, "packages": { "": { - "name": "@yaakapp/plugins", - "devDependencies": { - "@yaakapp/cli": "^0.0.8" - } - }, - "node_modules/@yaakapp/cli": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.8.tgz", - "integrity": "sha512-koE6zSDJj37blUIS9+W2VSeSK+UBQ4C80To7MdshorrTRjnTesNONF2GlDEbQrMnWC7PHdAhcHki/O52clxyeA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "golang-npm": "^0.0.6" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/golang-npm": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/golang-npm/-/golang-npm-0.0.6.tgz", - "integrity": "sha512-7vDCGw1xcdXDLKF+KWdtAvAW3XAxsQsn3rHYfBYSVR5xVgWkGpgCyfUJCapdtYAu3Hnwu3bkIfsOj4MvxpX4jw==", - "dev": true, - "dependencies": { - "mkdirp": "^3.0.1", - "node-fetch": "^2.7.0", - "tar": "^6.2.1" - }, - "bin": { - "golang-npm": "bin/index.js" - } - }, - "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "name": "@yaakapp/plugins" } } } diff --git a/plugins/importer-yaak/src/index.ts b/plugins/importer-yaak/src/index.ts index f50a13fdd..fc7daf58d 100644 --- a/plugins/importer-yaak/src/index.ts +++ b/plugins/importer-yaak/src/index.ts @@ -1,4 +1,4 @@ -export function pluginHookImport(ctx: any, contents: string) { +export function pluginHookImport(_ctx: any, contents: string) { let parsed; try { parsed = JSON.parse(contents); From 02fd8f22b2dccfcd437ca36251d6a0fbfc9234da Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 22 Jul 2024 09:46:18 -0700 Subject: [PATCH 011/996] Create README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..d90dd263c --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Yaak Plugins + +To-do From 373bc75e98f9079931ef24832412aa478d148c05 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 22 Jul 2024 14:04:37 -0700 Subject: [PATCH 012/996] OpenAPI import plugins --- .prettierrc.json | 8 + package-lock.json | 1416 ++++++++++++++++- package.json | 3 + plugins/exporter-curl/package.json | 1 - plugins/filter-jsonpath/package.json | 1 - plugins/filter-xpath/package.json | 3 - plugins/importer-curl/package.json | 1 - plugins/importer-insomnia/package.json | 1 - plugins/importer-insomnia/src/index.ts | 4 +- plugins/importer-openapi/package-lock.json | 920 +++++++++++ plugins/importer-openapi/package.json | 16 + plugins/importer-openapi/src/index.ts | 29 + .../tests/fixtures/petstore.yaml | 819 ++++++++++ plugins/importer-openapi/tests/index.test.ts | 23 + plugins/importer-postman/package.json | 1 + tsconfig.json | 1 - 16 files changed, 3235 insertions(+), 12 deletions(-) create mode 100644 .prettierrc.json create mode 100644 plugins/importer-openapi/package-lock.json create mode 100644 plugins/importer-openapi/package.json create mode 100644 plugins/importer-openapi/src/index.ts create mode 100644 plugins/importer-openapi/tests/fixtures/petstore.yaml create mode 100644 plugins/importer-openapi/tests/index.test.ts diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..9c0c1c01d --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": true, + "printWidth": 100, + "bracketSpacing": true +} diff --git a/package-lock.json b/package-lock.json index 2ea0cad32..9a7a76cfa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,7 +4,1421 @@ "requires": true, "packages": { "": { - "name": "@yaakapp/plugins" + "name": "@yaakapp/plugins", + "devDependencies": { + "vitest": "^2.0.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", + "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", + "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", + "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", + "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", + "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", + "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", + "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", + "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", + "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", + "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", + "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", + "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", + "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", + "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", + "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", + "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@vitest/expect": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.4.tgz", + "integrity": "sha512-39jr5EguIoanChvBqe34I8m1hJFI4+jxvdOpD7gslZrVQBKhh8H9eD7J/LJX4zakrw23W+dITQTDqdt43xVcJw==", + "dev": true, + "dependencies": { + "@vitest/spy": "2.0.4", + "@vitest/utils": "2.0.4", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.4.tgz", + "integrity": "sha512-RYZl31STbNGqf4l2eQM1nvKPXE0NhC6Eq0suTTePc4mtMQ1Fn8qZmjV4emZdEdG2NOWGKSCrHZjmTqDCDoeFBw==", + "dev": true, + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.4.tgz", + "integrity": "sha512-Gk+9Su/2H2zNfNdeJR124gZckd5st4YoSuhF1Rebi37qTXKnqYyFCd9KP4vl2cQHbtuVKjfEKrNJxHHCW8thbQ==", + "dev": true, + "dependencies": { + "@vitest/utils": "2.0.4", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.4.tgz", + "integrity": "sha512-or6Mzoz/pD7xTvuJMFYEtso1vJo1S5u6zBTinfl+7smGUhqybn6VjzCDMhmTyVOFWwkCMuNjmNNxnyXPgKDoPw==", + "dev": true, + "dependencies": { + "@vitest/pretty-format": "2.0.4", + "magic-string": "^0.30.10", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.4.tgz", + "integrity": "sha512-uTXU56TNoYrTohb+6CseP8IqNwlNdtPwEO0AWl+5j7NelS6x0xZZtP0bDWaLvOfUbaYwhhWp1guzXUxkC7mW7Q==", + "dev": true, + "dependencies": { + "tinyspy": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.4.tgz", + "integrity": "sha512-Zc75QuuoJhOBnlo99ZVUkJIuq4Oj0zAkrQ2VzCqNCx6wAwViHEh5Fnp4fiJTE9rA+sAoXRf00Z9xGgfEzV6fzQ==", + "dev": true, + "dependencies": { + "@vitest/pretty-format": "2.0.4", + "estree-walker": "^3.0.3", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "dev": true, + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "engines": { + "node": ">= 16" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/loupe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", + "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.19.0", + "@rollup/rollup-android-arm64": "4.19.0", + "@rollup/rollup-darwin-arm64": "4.19.0", + "@rollup/rollup-darwin-x64": "4.19.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", + "@rollup/rollup-linux-arm-musleabihf": "4.19.0", + "@rollup/rollup-linux-arm64-gnu": "4.19.0", + "@rollup/rollup-linux-arm64-musl": "4.19.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", + "@rollup/rollup-linux-riscv64-gnu": "4.19.0", + "@rollup/rollup-linux-s390x-gnu": "4.19.0", + "@rollup/rollup-linux-x64-gnu": "4.19.0", + "@rollup/rollup-linux-x64-musl": "4.19.0", + "@rollup/rollup-win32-arm64-msvc": "4.19.0", + "@rollup/rollup-win32-ia32-msvc": "4.19.0", + "@rollup/rollup-win32-x64-msvc": "4.19.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tinybench": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "dev": true + }, + "node_modules/tinypool": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.0.tgz", + "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==", + "dev": true, + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", + "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vite": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.39", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.4.tgz", + "integrity": "sha512-ZpJVkxcakYtig5iakNeL7N3trufe3M6vGuzYAr4GsbCTwobDeyPJpE4cjDhhPluv8OvQCFzu2LWp6GkoKRITXA==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.5", + "pathe": "^1.1.2", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.4.tgz", + "integrity": "sha512-luNLDpfsnxw5QSW4bISPe6tkxVvv5wn2BBs/PuDRkhXZ319doZyLOBr1sjfB5yCEpTiU7xCAdViM8TNVGPwoog==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@vitest/expect": "2.0.4", + "@vitest/pretty-format": "^2.0.4", + "@vitest/runner": "2.0.4", + "@vitest/snapshot": "2.0.4", + "@vitest/spy": "2.0.4", + "@vitest/utils": "2.0.4", + "chai": "^5.1.1", + "debug": "^4.3.5", + "execa": "^8.0.1", + "magic-string": "^0.30.10", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "tinybench": "^2.8.0", + "tinypool": "^1.0.0", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.0.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.0.4", + "@vitest/ui": "2.0.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } } } } diff --git a/package.json b/package.json index eadcd8ccd..64498c510 100644 --- a/package.json +++ b/package.json @@ -4,5 +4,8 @@ "private": true, "scripts": { "build": "node scripts/build-plugins.cjs" + }, + "devDependencies": { + "vitest": "^2.0.4" } } diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index f3d848687..51bf7380c 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -6,7 +6,6 @@ }, "devDependencies": { "@types/node": "^20.14.9", - "esbuild": "^0.21.5", "typescript": "^5.5.2", "vitest": "^1.4.0" } diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index 3e0397ea4..6f8dd35ec 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -10,7 +10,6 @@ "devDependencies": { "@types/jsonpath": "^0.2.4", "@types/node": "^20.14.9", - "esbuild": "^0.21.5", "typescript": "^5.5.2" } } diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index 82c910fad..062ad1eee 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -9,8 +9,5 @@ "@xmldom/xmldom": "^0.8.10", "typescript": "^5.5.2", "xpath": "^0.0.34" - }, - "devDependencies": { - "esbuild": "^0.21.5" } } diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index ceef1e0c6..a5eb5ca33 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -10,7 +10,6 @@ "devDependencies": { "@types/node": "^20.14.9", "@types/shell-quote": "^1.7.5", - "esbuild": "^0.21.5", "typescript": "^5.5.2", "vitest": "^1.4.0" } diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 55a646e3a..02d57fe07 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -9,7 +9,6 @@ }, "devDependencies": { "@types/node": "^20.14.9", - "esbuild": "^0.21.5", "typescript": "^5.5.2" } } diff --git a/plugins/importer-insomnia/src/index.ts b/plugins/importer-insomnia/src/index.ts index bad5f13c3..11aa7faa3 100644 --- a/plugins/importer-insomnia/src/index.ts +++ b/plugins/importer-insomnia/src/index.ts @@ -26,9 +26,7 @@ export function pluginHookImport(ctx: any, contents: string) { try { parsed = parsed ?? YAML.parse(contents); - } catch (e) { - console.log('FAILED', e); - } + } catch (e) { } if (!isJSObject(parsed)) return; if (!Array.isArray(parsed.resources)) return; diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json new file mode 100644 index 000000000..cdc308c98 --- /dev/null +++ b/plugins/importer-openapi/package-lock.json @@ -0,0 +1,920 @@ +{ + "name": "importer-postman", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "importer-postman", + "version": "0.0.1", + "dependencies": { + "openapi-to-postmanv2": "^4.23.1", + "yaml": "^2.4.2" + }, + "devDependencies": { + "@types/node": "^20.14.9", + "@types/openapi-to-postmanv2": "^3.2.4", + "typescript": "^5.5.2" + } + }, + "node_modules/@exodus/schemasafe": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", + "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==" + }, + "node_modules/@faker-js/faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-R11tGE6yIFwqpaIqcfkcg7AICXzFg14+5h5v0TfF/9+RMDL6jhzCy/pxHVOfbALGdtVYdt6JdR21tuxEgl34dw==" + }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/openapi-to-postmanv2": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@types/openapi-to-postmanv2/-/openapi-to-postmanv2-3.2.4.tgz", + "integrity": "sha512-5SMU3TY2gmQRs6Ri7WRlI7tF2QEK0K4GfL50ghAPOUv4NkxhG37Aq2qystytm9fcmUgHDfyrkwZyprRgp85mxg==", + "dev": true, + "dependencies": { + "@types/postman-collection": "*" + } + }, + "node_modules/@types/postman-collection": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/postman-collection/-/postman-collection-3.5.10.tgz", + "integrity": "sha512-l8xAUZNW9MzKWyeWuPgQlnyvpX8beeLqXYZTixr55Figae8/0gFb5l5GcU1y+3yeDmbXdY57cGxdvu+4OGbMdg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" + }, + "node_modules/charset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/charset/-/charset-1.0.1.tgz", + "integrity": "sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/compute-gcd": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", + "integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==", + "dependencies": { + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, + "node_modules/compute-lcm": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz", + "integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==", + "dependencies": { + "compute-gcd": "^1.2.1", + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==" + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/graphlib": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/http-reasons": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/http-reasons/-/http-reasons-0.1.0.tgz", + "integrity": "sha512-P6kYh0lKZ+y29T2Gqz+RlC9WBLhKe8kDmcJ+A+611jFfxdPsbMRQ5aNmFRM3lENqFkK+HTTL+tlQviAiv0AbLQ==" + }, + "node_modules/http2-client": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", + "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==" + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-compare": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", + "integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==", + "dependencies": { + "lodash": "^4.17.4" + } + }, + "node_modules/json-schema-merge-allof": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", + "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", + "dependencies": { + "compute-lcm": "^1.1.2", + "json-schema-compare": "^0.2.2", + "lodash": "^4.17.20" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/liquid-json": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/liquid-json/-/liquid-json-0.3.1.tgz", + "integrity": "sha512-wUayTU8MS827Dam6MxgD72Ui+KOSF+u/eIqpatOtjnvgJ0+mnDq33uC2M7J0tPK+upe/DpUAuK4JUU89iBoNKQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-format": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mime-format/-/mime-format-2.0.1.tgz", + "integrity": "sha512-XxU3ngPbEnrYnNbIX+lYSaYg0M01v6p2ntd2YaFksTu0vayaw5OJvbdRyWs07EYRlLED5qadUZ+xo+XhOvFhwg==", + "dependencies": { + "charset": "^1.0.0" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch-h2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz", + "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==", + "dependencies": { + "http2-client": "^1.2.5" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-readfiles": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", + "integrity": "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==", + "dependencies": { + "es6-promise": "^3.2.1" + } + }, + "node_modules/oas-kit-common": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", + "integrity": "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==", + "dependencies": { + "fast-safe-stringify": "^2.0.7" + } + }, + "node_modules/oas-linter": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/oas-linter/-/oas-linter-3.2.2.tgz", + "integrity": "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==", + "dependencies": { + "@exodus/schemasafe": "^1.0.0-rc.2", + "should": "^13.2.1", + "yaml": "^1.10.0" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-linter/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/oas-resolver": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", + "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", + "dependencies": { + "node-fetch-h2": "^2.3.0", + "oas-kit-common": "^1.0.8", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + }, + "bin": { + "resolve": "resolve.js" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-resolver-browser": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/oas-resolver-browser/-/oas-resolver-browser-2.5.6.tgz", + "integrity": "sha512-Jw5elT/kwUJrnGaVuRWe1D7hmnYWB8rfDDjBnpQ+RYY/dzAewGXeTexXzt4fGEo6PUE4eqKqPWF79MZxxvMppA==", + "dependencies": { + "node-fetch-h2": "^2.3.0", + "oas-kit-common": "^1.0.8", + "path-browserify": "^1.0.1", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + }, + "bin": { + "resolve": "resolve.js" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-resolver-browser/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/oas-resolver/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/oas-schema-walker": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", + "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==", + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-validator": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", + "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", + "dependencies": { + "call-me-maybe": "^1.0.1", + "oas-kit-common": "^1.0.8", + "oas-linter": "^3.2.2", + "oas-resolver": "^2.5.6", + "oas-schema-walker": "^1.1.5", + "reftools": "^1.1.9", + "should": "^13.2.1", + "yaml": "^1.10.0" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-validator/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/openapi-to-postmanv2": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/openapi-to-postmanv2/-/openapi-to-postmanv2-4.23.1.tgz", + "integrity": "sha512-vNGU95euiXriNw7sVJ82uZyCyV8rXxSkc5o8bcDQh2IonO6cwzVUbrfYPnnj6A18YTGHSWHhQpUy0otxDHFoCw==", + "dependencies": { + "ajv": "8.11.0", + "ajv-draft-04": "1.0.0", + "ajv-formats": "2.1.1", + "async": "3.2.4", + "commander": "2.20.3", + "graphlib": "2.1.8", + "js-yaml": "4.1.0", + "json-schema-merge-allof": "0.8.1", + "lodash": "4.17.21", + "oas-resolver-browser": "2.5.6", + "object-hash": "3.0.0", + "path-browserify": "1.0.1", + "postman-collection": "^4.4.0", + "swagger2openapi": "7.0.8", + "traverse": "0.6.6", + "yaml": "1.10.2" + }, + "bin": { + "openapi2postmanv2": "bin/openapi2postmanv2.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/openapi-to-postmanv2/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "node_modules/postman-collection": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.4.0.tgz", + "integrity": "sha512-2BGDFcUwlK08CqZFUlIC8kwRJueVzPjZnnokWPtJCd9f2J06HBQpGL7t2P1Ud1NEsK9NHq9wdipUhWLOPj5s/Q==", + "dependencies": { + "@faker-js/faker": "5.5.3", + "file-type": "3.9.0", + "http-reasons": "0.1.0", + "iconv-lite": "0.6.3", + "liquid-json": "0.3.1", + "lodash": "4.17.21", + "mime-format": "2.0.1", + "mime-types": "2.1.35", + "postman-url-encoder": "3.0.5", + "semver": "7.5.4", + "uuid": "8.3.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/postman-url-encoder": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postman-url-encoder/-/postman-url-encoder-3.0.5.tgz", + "integrity": "sha512-jOrdVvzUXBC7C+9gkIkpDJ3HIxOHTIqjpQ4C1EMt1ZGeMvSEpbFCKq23DEfgsj46vMnDgyQf+1ZLp2Wm+bKSsA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/reftools": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", + "integrity": "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==", + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/should": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", + "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", + "dependencies": { + "should-equal": "^2.0.0", + "should-format": "^3.0.3", + "should-type": "^1.4.0", + "should-type-adaptors": "^1.0.1", + "should-util": "^1.0.0" + } + }, + "node_modules/should-equal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", + "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", + "dependencies": { + "should-type": "^1.4.0" + } + }, + "node_modules/should-format": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", + "dependencies": { + "should-type": "^1.3.0", + "should-type-adaptors": "^1.0.1" + } + }, + "node_modules/should-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==" + }, + "node_modules/should-type-adaptors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", + "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", + "dependencies": { + "should-type": "^1.3.0", + "should-util": "^1.0.0" + } + }, + "node_modules/should-util": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", + "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/swagger2openapi": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/swagger2openapi/-/swagger2openapi-7.0.8.tgz", + "integrity": "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==", + "dependencies": { + "call-me-maybe": "^1.0.1", + "node-fetch": "^2.6.1", + "node-fetch-h2": "^2.3.0", + "node-readfiles": "^0.2.0", + "oas-kit-common": "^1.0.8", + "oas-resolver": "^2.5.6", + "oas-schema-walker": "^1.1.5", + "oas-validator": "^5.0.8", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + }, + "bin": { + "boast": "boast.js", + "oas-validate": "oas-validate.js", + "swagger2openapi": "swagger2openapi.js" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/swagger2openapi/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" + }, + "node_modules/typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate.io-array": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz", + "integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==" + }, + "node_modules/validate.io-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz", + "integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==" + }, + "node_modules/validate.io-integer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz", + "integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==", + "dependencies": { + "validate.io-number": "^1.0.3" + } + }, + "node_modules/validate.io-integer-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz", + "integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==", + "dependencies": { + "validate.io-array": "^1.0.3", + "validate.io-integer": "^1.0.4" + } + }, + "node_modules/validate.io-number": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz", + "integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json new file mode 100644 index 000000000..a60cd1e7d --- /dev/null +++ b/plugins/importer-openapi/package.json @@ -0,0 +1,16 @@ +{ + "name": "importer-postman", + "version": "0.0.1", + "scripts": { + "build": "yaakcli ./src/index.js" + }, + "dependencies": { + "openapi-to-postmanv2": "^4.23.1", + "yaml": "^2.4.2" + }, + "devDependencies": { + "@types/node": "^20.14.9", + "@types/openapi-to-postmanv2": "^3.2.4", + "typescript": "^5.5.2" + } +} diff --git a/plugins/importer-openapi/src/index.ts b/plugins/importer-openapi/src/index.ts new file mode 100644 index 000000000..3171a628a --- /dev/null +++ b/plugins/importer-openapi/src/index.ts @@ -0,0 +1,29 @@ +import { convert } from 'openapi-to-postmanv2'; +import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman/build'; +import { Folder, HttpRequest, Workspace, Environment } from '../../../types/models'; + +type AtLeast = Partial & Pick; + +interface ExportResources { + workspaces: AtLeast[]; + environments: AtLeast[]; + httpRequests: AtLeast[]; + folders: AtLeast[]; +} + +export async function pluginHookImport( + ctx: any, + contents: string, +): Promise<{ resources: ExportResources } | undefined> { + const result = await new Promise((resolve, reject) => { + convert({ type: 'string', data: contents }, {}, (err, result) => { + if (err != null) reject(err); + + if (Array.isArray(result.output) && result.output.length > 0) { + resolve(JSON.stringify(result.output[0].data)); + } + }); + }); + + return pluginHookImportPostman(ctx, result); +} diff --git a/plugins/importer-openapi/tests/fixtures/petstore.yaml b/plugins/importer-openapi/tests/fixtures/petstore.yaml new file mode 100644 index 000000000..f5271a595 --- /dev/null +++ b/plugins/importer-openapi/tests/fixtures/petstore.yaml @@ -0,0 +1,819 @@ +openapi: 3.0.2 +servers: + - url: /v3 +info: + description: |- + This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about + Swagger at [http://swagger.io](http://swagger.io). In the third iteration of the pet store, we've switched to the design first approach! + You can now help us improve the API whether it's by making changes to the definition itself or to the code. + That way, with time, we can improve the API in general, and expose some of the new features in OAS3. + + Some useful links: + - [The Pet Store repository](https://github.com/swagger-api/swagger-petstore) + - [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml) + version: 1.0.20-SNAPSHOT + title: Swagger Petstore - OpenAPI 3.0 + termsOfService: 'http://swagger.io/terms/' + contact: + email: apiteam@swagger.io + license: + name: Apache 2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0.html' +tags: + - name: pet + description: Everything about your Pets + externalDocs: + description: Find out more + url: 'http://swagger.io' + - name: store + description: Access to Petstore orders + externalDocs: + description: Find out more about our store + url: 'http://swagger.io' + - name: user + description: Operations about user +paths: + /pet: + post: + tags: + - pet + summary: Add a new pet to the store + description: Add a new pet to the store + operationId: addPet + responses: + '200': + description: Successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + description: Create a new pet in the store + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Pet' + put: + tags: + - pet + summary: Update an existing pet + description: Update an existing pet by Id + operationId: updatePet + responses: + '200': + description: Successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + description: Update an existent pet in the store + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Pet' + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: false + explode: true + schema: + type: string + enum: + - available + - pending + - sold + default: available + responses: + '200': + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid status value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + /pet/findByTags: + get: + tags: + - pet + summary: Finds Pets by tags + description: >- + Multiple tags can be provided with comma separated strings. Use tag1, + tag2, tag3 for testing. + operationId: findPetsByTags + parameters: + - name: tags + in: query + description: Tags to filter by + required: false + explode: true + schema: + type: array + items: + type: string + responses: + '200': + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid tag value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + '/pet/{petId}': + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + security: + - api_key: [] + - petstore_auth: + - 'write:pets' + - 'read:pets' + post: + tags: + - pet + summary: Updates a pet in the store with form data + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + format: int64 + - name: name + in: query + description: Name of pet that needs to be updated + schema: + type: string + - name: status + in: query + description: Status of pet that needs to be updated + schema: + type: string + responses: + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + delete: + tags: + - pet + summary: Deletes a pet + description: '' + operationId: deletePet + parameters: + - name: api_key + in: header + description: '' + required: false + schema: + type: string + - name: petId + in: path + description: Pet id to delete + required: true + schema: + type: integer + format: int64 + responses: + '400': + description: Invalid pet value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + '/pet/{petId}/uploadImage': + post: + tags: + - pet + summary: uploads an image + description: '' + operationId: uploadFile + parameters: + - name: petId + in: path + description: ID of pet to update + required: true + schema: + type: integer + format: int64 + - name: additionalMetadata + in: query + description: Additional Metadata + required: false + schema: + type: string + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + content: + application/octet-stream: + schema: + type: string + format: binary + /store/inventory: + get: + tags: + - store + summary: Returns pet inventories by status + description: Returns a map of status codes to quantities + operationId: getInventory + x-swagger-router-controller: OrderController + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + additionalProperties: + type: integer + format: int32 + security: + - api_key: [] + /store/order: + post: + tags: + - store + summary: Place an order for a pet + description: Place a new order in the store + operationId: placeOrder + x-swagger-router-controller: OrderController + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + '405': + description: Invalid input + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Order' + '/store/order/{orderId}': + get: + tags: + - store + summary: Find purchase order by ID + x-swagger-router-controller: OrderController + description: >- + For valid response try integer IDs with value <= 5 or > 10. Other values + will generate exceptions. + operationId: getOrderById + parameters: + - name: orderId + in: path + description: ID of order that needs to be fetched + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/json: + schema: + $ref: '#/components/schemas/Order' + '400': + description: Invalid ID supplied + '404': + description: Order not found + delete: + tags: + - store + summary: Delete purchase order by ID + x-swagger-router-controller: OrderController + description: >- + For valid response try integer IDs with value < 1000. Anything above + 1000 or nonintegers will generate API errors + operationId: deleteOrder + parameters: + - name: orderId + in: path + description: ID of the order that needs to be deleted + required: true + schema: + type: integer + format: int64 + responses: + '400': + description: Invalid ID supplied + '404': + description: Order not found + /user: + post: + tags: + - user + summary: Create user + description: This can only be done by the logged in user. + operationId: createUser + responses: + default: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/User' + application/xml: + schema: + $ref: '#/components/schemas/User' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' + application/xml: + schema: + $ref: '#/components/schemas/User' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/User' + description: Created user object + /user/createWithList: + post: + tags: + - user + summary: Creates list of users with given input array + description: 'Creates list of users with given input array' + x-swagger-router-controller: UserController + operationId: createUsersWithListInput + responses: + '200': + description: Successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/User' + application/json: + schema: + $ref: '#/components/schemas/User' + default: + description: successful operation + requestBody: + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + /user/login: + get: + tags: + - user + summary: Logs user into the system + description: '' + operationId: loginUser + parameters: + - name: username + in: query + description: The user name for login + required: false + schema: + type: string + - name: password + in: query + description: The password for login in clear text + required: false + schema: + type: string + responses: + '200': + description: successful operation + headers: + X-Rate-Limit: + description: calls per hour allowed by the user + schema: + type: integer + format: int32 + X-Expires-After: + description: date in UTC when token expires + schema: + type: string + format: date-time + content: + application/xml: + schema: + type: string + application/json: + schema: + type: string + '400': + description: Invalid username/password supplied + /user/logout: + get: + tags: + - user + summary: Logs out current logged in user session + description: '' + operationId: logoutUser + parameters: [] + responses: + default: + description: successful operation + '/user/{username}': + get: + tags: + - user + summary: Get user by user name + description: '' + operationId: getUserByName + parameters: + - name: username + in: path + description: 'The name that needs to be fetched. Use user1 for testing. ' + required: true + schema: + type: string + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/User' + application/json: + schema: + $ref: '#/components/schemas/User' + '400': + description: Invalid username supplied + '404': + description: User not found + put: + tags: + - user + summary: Update user + x-swagger-router-controller: UserController + description: This can only be done by the logged in user. + operationId: updateUser + parameters: + - name: username + in: path + description: name that needs to be updated + required: true + schema: + type: string + responses: + default: + description: successful operation + requestBody: + description: Update an existent user in the store + content: + application/json: + schema: + $ref: '#/components/schemas/User' + application/xml: + schema: + $ref: '#/components/schemas/User' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/User' + delete: + tags: + - user + summary: Delete user + description: This can only be done by the logged in user. + operationId: deleteUser + parameters: + - name: username + in: path + description: The name that needs to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid username supplied + '404': + description: User not found +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + schemas: + Order: + x-swagger-router-model: io.swagger.petstore.model.Order + properties: + id: + type: integer + format: int64 + example: 10 + petId: + type: integer + format: int64 + example: 198772 + quantity: + type: integer + format: int32 + example: 7 + shipDate: + type: string + format: date-time + status: + type: string + description: Order Status + enum: + - placed + - approved + - delivered + example: approved + complete: + type: boolean + xml: + name: order + type: object + Customer: + properties: + id: + type: integer + format: int64 + example: 100000 + username: + type: string + example: fehguy + address: + type: array + items: + $ref: '#/components/schemas/Address' + xml: + wrapped: true + name: addresses + xml: + name: customer + type: object + Address: + properties: + street: + type: string + example: 437 Lytton + city: + type: string + example: Palo Alto + state: + type: string + example: CA + zip: + type: string + example: 94301 + xml: + name: address + type: object + Category: + x-swagger-router-model: io.swagger.petstore.model.Category + properties: + id: + type: integer + format: int64 + example: 1 + name: + type: string + example: Dogs + xml: + name: category + type: object + User: + x-swagger-router-model: io.swagger.petstore.model.User + properties: + id: + type: integer + format: int64 + example: 10 + username: + type: string + example: theUser + firstName: + type: string + example: John + lastName: + type: string + example: James + email: + type: string + example: john@email.com + password: + type: string + example: 12345 + phone: + type: string + example: 12345 + userStatus: + type: integer + format: int32 + example: 1 + description: User Status + xml: + name: user + type: object + Tag: + x-swagger-router-model: io.swagger.petstore.model.Tag + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: tag + type: object + Pet: + x-swagger-router-model: io.swagger.petstore.model.Pet + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + example: 10 + name: + type: string + example: doggie + category: + $ref: '#/components/schemas/Category' + photoUrls: + type: array + xml: + wrapped: true + items: + type: string + xml: + name: photoUrl + tags: + type: array + xml: + wrapped: true + items: + $ref: '#/components/schemas/Tag' + xml: + name: tag + status: + type: string + description: pet status in the store + enum: + - available + - pending + - sold + xml: + name: pet + type: object + ApiResponse: + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string + xml: + name: '##default' + type: object + requestBodies: + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + UserArray: + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + description: List of user object + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'https://petstore.swagger.io/oauth/authorize' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header diff --git a/plugins/importer-openapi/tests/index.test.ts b/plugins/importer-openapi/tests/index.test.ts new file mode 100644 index 000000000..c8e30a63e --- /dev/null +++ b/plugins/importer-openapi/tests/index.test.ts @@ -0,0 +1,23 @@ +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { describe, expect, test } from 'vitest'; +import { pluginHookImport } from '../src'; + +describe('importer-openapi', () => { + const p = path.join(__dirname, 'fixtures'); + const fixtures = fs.readdirSync(p); + + for (const fixture of fixtures) { + test('Imports ' + fixture, async () => { + const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); + const imported = await pluginHookImport({}, contents); + expect(imported?.resources.workspaces).toEqual([ + expect.objectContaining({ + name: 'Swagger Petstore - OpenAPI 3.0', + }), + ]); + expect(imported?.resources.httpRequests.length).toBe(19); + expect(imported?.resources.folders.length).toBe(7); + }); + } +}); diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 3265cadf5..995ec4183 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -1,6 +1,7 @@ { "name": "importer-postman", "version": "0.0.1", + "main": "./build/index.js", "scripts": { "build": "yaakcli ./src/index.js" }, diff --git a/tsconfig.json b/tsconfig.json index db795350b..a1d44dcb4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,6 @@ "types", "plugins" ], - "exclude": ["plugins/*/node_modules"], "compilerOptions": { "target": "es2021", "lib": ["DOM", "DOM.Iterable", "ESNext"], From 6a24b31c6ca776380c638e9dbd6edd58fe248412 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 22 Jul 2024 18:00:13 -0700 Subject: [PATCH 013/996] Improved Postman and OpenAPI import --- plugins/filter-jsonpath/package.json | 2 +- plugins/importer-openapi/package.json | 2 +- plugins/importer-openapi/src/index.ts | 24 +++++--- plugins/importer-openapi/tests/index.test.ts | 6 ++ plugins/importer-postman/src/index.ts | 62 ++++++++++++++++---- 5 files changed, 73 insertions(+), 23 deletions(-) diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index 6f8dd35ec..a2dbef37d 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -2,7 +2,7 @@ "name": "filter-jsonpath", "version": "0.0.1", "scripts": { - "build": "yaakcli src/index.ts" + "build": "BUILD_PLATFORM=browser yaakcli src/index.ts" }, "dependencies": { "jsonpath": "^1.1.1" diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index a60cd1e7d..2164487e6 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -1,5 +1,5 @@ { - "name": "importer-postman", + "name": "importer-openapi", "version": "0.0.1", "scripts": { "build": "yaakcli ./src/index.js" diff --git a/plugins/importer-openapi/src/index.ts b/plugins/importer-openapi/src/index.ts index 3171a628a..9a73f92db 100644 --- a/plugins/importer-openapi/src/index.ts +++ b/plugins/importer-openapi/src/index.ts @@ -1,5 +1,5 @@ import { convert } from 'openapi-to-postmanv2'; -import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman/build'; +import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman'; import { Folder, HttpRequest, Workspace, Environment } from '../../../types/models'; type AtLeast = Partial & Pick; @@ -15,15 +15,21 @@ export async function pluginHookImport( ctx: any, contents: string, ): Promise<{ resources: ExportResources } | undefined> { - const result = await new Promise((resolve, reject) => { - convert({ type: 'string', data: contents }, {}, (err, result) => { - if (err != null) reject(err); + let postmanCollection; + try { + postmanCollection = await new Promise((resolve, reject) => { + convert({ type: 'string', data: contents }, {}, (err, result) => { + if (err != null) reject(err); - if (Array.isArray(result.output) && result.output.length > 0) { - resolve(JSON.stringify(result.output[0].data)); - } + if (Array.isArray(result.output) && result.output.length > 0) { + resolve(result.output[0].data); + } + }); }); - }); + } catch (err) { + // Probably not an OpenAPI file, so skip it + return undefined; + } - return pluginHookImportPostman(ctx, result); + return pluginHookImportPostman(ctx, JSON.stringify(postmanCollection)); } diff --git a/plugins/importer-openapi/tests/index.test.ts b/plugins/importer-openapi/tests/index.test.ts index c8e30a63e..f89dcf7d4 100644 --- a/plugins/importer-openapi/tests/index.test.ts +++ b/plugins/importer-openapi/tests/index.test.ts @@ -7,6 +7,11 @@ describe('importer-openapi', () => { const p = path.join(__dirname, 'fixtures'); const fixtures = fs.readdirSync(p); + test('Skips invalid file', async () => { + const imported = await pluginHookImport({}, '{}'); + expect(imported).toBeUndefined(); + }) + for (const fixture of fixtures) { test('Imports ' + fixture, async () => { const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); @@ -14,6 +19,7 @@ describe('importer-openapi', () => { expect(imported?.resources.workspaces).toEqual([ expect.objectContaining({ name: 'Swagger Petstore - OpenAPI 3.0', + description: expect.stringContaining('This is a sample Pet Store Server'), }), ]); expect(imported?.resources.httpRequests.length).toBe(19); diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts index d4aa2755f..57263d2aa 100644 --- a/plugins/importer-postman/src/index.ts +++ b/plugins/importer-postman/src/index.ts @@ -39,7 +39,7 @@ export function pluginHookImport( model: 'workspace', id: generateId('workspace'), name: info.name || 'Postman Import', - description: info.description || '', + description: info.description?.content ?? info.description ?? '', variables: root.variable?.map((v: any) => ({ name: v.key, @@ -73,7 +73,7 @@ export function pluginHookImport( folderId, name: v.name, method: r.method || 'GET', - url: typeof r.url === 'string' ? r.url : toRecord(r.url).raw, + url: typeof r.url === 'string' ? r.url : convertUrl(toRecord(r.url)), body: bodyPatch.body, bodyType: bodyPatch.bodyType, authentication: authPatch.authentication, @@ -103,6 +103,43 @@ export function pluginHookImport( return { resources: convertTemplateSyntax(exportResources) }; } +function convertUrl(url: Record) { + if ('raw' in url) { + return url.raw; + } + + let v = ''; + + if ('protocol' in url && typeof url.protocol === 'string') { + v += `${url.protocol}://`; + } + + if ('host' in url) { + v += `${Array.isArray(url.host) ? url.host.join('.') : url.host}`; + } + + if ('port' in url && typeof url.port === 'string') { + v += `:${url.port}`; + } + + if ('path' in url && Array.isArray(url.path) && url.path.length > 0) { + v += `/${Array.isArray(url.path) ? url.path.join('/') : url.path}`; + } + + if ('query' in url && Array.isArray(url.query) && url.query.length > 0) { + const qs = url.query.map(q => `${q.key ?? ''}=${q.value ?? ''}`).join('&'); + v += `?${qs}`; + } + + if ('hash' in url && typeof url.hash === 'string') { + v += `#${url.hash}`; + } + + // TODO: Implement url.variables (path variables) + + return v; +} + function importAuth( rawAuth: any, ): Pick { @@ -181,16 +218,16 @@ function importBody(rawBody: any): Pick f.src != null ? { - enabled: !f.disabled, - contentType: f.contentType ?? null, - name: f.key ?? '', - file: f.src ?? '', - } + enabled: !f.disabled, + contentType: f.contentType ?? null, + name: f.key ?? '', + file: f.src ?? '', + } : { - enabled: !f.disabled, - name: f.key ?? '', - value: f.value ?? '', - }, + enabled: !f.disabled, + name: f.key ?? '', + value: f.value ?? '', + }, ), }, }; @@ -216,7 +253,8 @@ function importBody(rawBody: any): Pick | null { try { return toRecord(JSON.parse(jsonStr)); - } catch (err) {} + } catch (err) { + } return null; } From 27e6668be5ac850322db056ad28b698b08d46a02 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 22 Jul 2024 18:03:17 -0700 Subject: [PATCH 014/996] Try fix import --- plugins/importer-openapi/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/importer-openapi/src/index.ts b/plugins/importer-openapi/src/index.ts index 9a73f92db..8ba281a8c 100644 --- a/plugins/importer-openapi/src/index.ts +++ b/plugins/importer-openapi/src/index.ts @@ -1,5 +1,5 @@ import { convert } from 'openapi-to-postmanv2'; -import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman'; +import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman/src/index'; import { Folder, HttpRequest, Workspace, Environment } from '../../../types/models'; type AtLeast = Partial & Pick; From 5db8f9117fef95d75b806e1b8792335b5a605487 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 22 Jul 2024 18:44:33 -0700 Subject: [PATCH 015/996] Use cross-env --- plugins/filter-jsonpath/package-lock.json | 830 ++-------------------- plugins/filter-jsonpath/package.json | 3 +- 2 files changed, 66 insertions(+), 767 deletions(-) diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index bd740bf69..64f9f06e8 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -13,592 +13,10 @@ "devDependencies": { "@types/jsonpath": "^0.2.4", "@types/node": "^20.14.9", - "typescript": "^5.5.2", - "vite": "^5.3.2" + "cross-env": "^7.0.3", + "typescript": "^5.5.2" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", - "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", - "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", - "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", - "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", - "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", - "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", - "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", - "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", - "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", - "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", - "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", - "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", - "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", - "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", - "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", - "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, "node_modules/@types/jsonpath": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.4.tgz", @@ -614,49 +32,43 @@ "undici-types": "~5.26.4" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", "dev": true, - "hasInstallScript": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, "bin": { - "esbuild": "bin/esbuild" + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" }, "engines": { - "node": ">=12" + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "engines": { + "node": ">= 8" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, "node_modules/escodegen": { "version": "1.14.3", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", @@ -723,19 +135,11 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/jsonpath": { "version": "1.1.1", @@ -759,24 +163,6 @@ "node": ">= 0.8.0" } }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -793,38 +179,13 @@ "node": ">= 0.8.0" } }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=8" } }, "node_modules/prelude-ls": { @@ -835,39 +196,25 @@ "node": ">= 0.8.0" } }, - "node_modules/rollup": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", - "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.0", - "@rollup/rollup-android-arm64": "4.18.0", - "@rollup/rollup-darwin-arm64": "4.18.0", - "@rollup/rollup-darwin-x64": "4.18.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", - "@rollup/rollup-linux-arm-musleabihf": "4.18.0", - "@rollup/rollup-linux-arm64-gnu": "4.18.0", - "@rollup/rollup-linux-arm64-musl": "4.18.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", - "@rollup/rollup-linux-riscv64-gnu": "4.18.0", - "@rollup/rollup-linux-s390x-gnu": "4.18.0", - "@rollup/rollup-linux-x64-gnu": "4.18.0", - "@rollup/rollup-linux-x64-musl": "4.18.0", - "@rollup/rollup-win32-arm64-msvc": "4.18.0", - "@rollup/rollup-win32-ia32-msvc": "4.18.0", - "@rollup/rollup-win32-x64-msvc": "4.18.0", - "fsevents": "~2.3.2" + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/source-map": { @@ -879,15 +226,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/static-eval": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", @@ -931,59 +269,19 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, - "node_modules/vite": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", - "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.38", - "rollup": "^4.13.0" + "isexe": "^2.0.0" }, "bin": { - "vite": "bin/vite.js" + "node-which": "bin/node-which" }, "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } + "node": ">= 8" } }, "node_modules/word-wrap": { diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index a2dbef37d..fb4301949 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -2,7 +2,7 @@ "name": "filter-jsonpath", "version": "0.0.1", "scripts": { - "build": "BUILD_PLATFORM=browser yaakcli src/index.ts" + "build": "cross-env BUILD_PLATFORM=browser yaakcli src/index.ts" }, "dependencies": { "jsonpath": "^1.1.1" @@ -10,6 +10,7 @@ "devDependencies": { "@types/jsonpath": "^0.2.4", "@types/node": "^20.14.9", + "cross-env": "^7.0.3", "typescript": "^5.5.2" } } From afaf4e62d8a7935b55b58d70ab0acb4b60925bf3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 23 Jul 2024 08:26:00 -0700 Subject: [PATCH 016/996] Better body handling in Postman --- plugins/importer-openapi/src/index.ts | 2 ++ plugins/importer-postman/src/index.ts | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/plugins/importer-openapi/src/index.ts b/plugins/importer-openapi/src/index.ts index 8ba281a8c..ee1cc66ff 100644 --- a/plugins/importer-openapi/src/index.ts +++ b/plugins/importer-openapi/src/index.ts @@ -31,5 +31,7 @@ export async function pluginHookImport( return undefined; } + // console.log("HELLO", JSON.stringify(postmanCollection, null, 1)); + return pluginHookImportPostman(ctx, JSON.stringify(postmanCollection)); } diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts index 57263d2aa..f946ce8b8 100644 --- a/plugins/importer-postman/src/index.ts +++ b/plugins/importer-postman/src/index.ts @@ -168,7 +168,7 @@ function importAuth( function importBody(rawBody: any): Pick { const body = toRecord(rawBody); - if ('graphql' in body) { + if (body.mode === 'graphql') { return { headers: [ { @@ -186,7 +186,7 @@ function importBody(rawBody: any): Pick Date: Tue, 23 Jul 2024 12:41:01 -0700 Subject: [PATCH 017/996] Don't add duplicate body headers for Postman --- plugins/importer-postman/src/index.ts | 45 ++++++++++++++++----------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts index f946ce8b8..a96ab7d98 100644 --- a/plugins/importer-postman/src/index.ts +++ b/plugins/importer-postman/src/index.ts @@ -1,4 +1,5 @@ -import { Environment, Folder, HttpRequest, Model, Workspace } from '../../../types/models'; +import { root } from 'postcss'; +import { Environment, Folder, HttpHeader, HttpRequest, Model, Workspace } from '../../../types/models'; const POSTMAN_2_1_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'; const POSTMAN_2_0_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json'; @@ -66,6 +67,24 @@ export function pluginHookImport( const bodyPatch = importBody(r.body); const requestAuthPath = importAuth(r.auth); const authPatch = requestAuthPath.authenticationType == null ? globalAuth : requestAuthPath; + + const headers: HttpHeader[] = toArray(r.header).map((h) => { + return { + name: h.key, + value: h.value, + enabled: !h.disabled, + }; + }); + + // Add body headers only if they don't already exist + for (const bodyPatchHeader of bodyPatch.headers) { + const existingHeader = headers.find(h => h.name.toLowerCase() === bodyPatchHeader.name.toLowerCase()); + if (existingHeader) { + continue; + } + headers.push(bodyPatchHeader); + } + const request: ExportResources['httpRequests'][0] = { model: 'http_request', id: generateId('http_request'), @@ -78,17 +97,7 @@ export function pluginHookImport( bodyType: bodyPatch.bodyType, authentication: authPatch.authentication, authenticationType: authPatch.authenticationType, - headers: [ - ...bodyPatch.headers, - ...authPatch.headers, - ...toArray(r.header).map((h) => { - return { - name: h.key, - value: h.value, - enabled: !h.disabled, - }; - }), - ], + headers, }; exportResources.httpRequests.push(request); } else { @@ -142,11 +151,10 @@ function convertUrl(url: Record) { function importAuth( rawAuth: any, -): Pick { +): Pick { const auth = toRecord(rawAuth); if ('basic' in auth) { return { - headers: [], authenticationType: 'basic', authentication: { username: auth.basic.username || '', @@ -155,14 +163,13 @@ function importAuth( }; } else if ('bearer' in auth) { return { - headers: [], authenticationType: 'bearer', authentication: { token: auth.bearer.token || '', }, }; } else { - return { headers: [], authenticationType: null, authentication: {} }; + return { authenticationType: null, authentication: {} }; } } @@ -250,9 +257,9 @@ function importBody(rawBody: any): Pick Date: Thu, 15 Aug 2024 06:17:33 -0700 Subject: [PATCH 018/996] Add @yaakapp/api everywhere --- package-lock.json | 22 + plugins/exporter-curl/package-lock.json | 26 +- plugins/exporter-curl/package.json | 3 + plugins/exporter-curl/src/index.ts | 20 +- plugins/filter-jsonpath/package-lock.json | 22 + plugins/filter-jsonpath/package.json | 3 +- plugins/filter-jsonpath/src/index.ts | 3 +- plugins/filter-xpath/package-lock.json | 796 +------------------- plugins/filter-xpath/package.json | 1 + plugins/filter-xpath/src/index.ts | 11 +- plugins/importer-curl/package-lock.json | 23 +- plugins/importer-curl/package.json | 1 + plugins/importer-curl/src/index.ts | 20 +- plugins/importer-insomnia/package-lock.json | 796 +------------------- plugins/importer-insomnia/package.json | 1 + plugins/importer-insomnia/src/index.ts | 10 +- plugins/importer-openapi/package-lock.json | 26 +- plugins/importer-openapi/package.json | 1 + plugins/importer-openapi/src/index.ts | 5 +- plugins/importer-postman/package-lock.json | 26 +- plugins/importer-postman/package.json | 3 + plugins/importer-postman/src/index.ts | 7 +- plugins/importer-yaak/package-lock.json | 407 +--------- plugins/importer-yaak/package.json | 3 + plugins/importer-yaak/src/index.ts | 6 +- 25 files changed, 258 insertions(+), 1984 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9a7a76cfa..79b5839e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,9 @@ "packages": { "": { "name": "@yaakapp/plugins", + "dependencies": { + "xml-formatter": "^3.6.3" + }, "devDependencies": { "vitest": "^2.0.4" } @@ -1419,6 +1422,25 @@ "engines": { "node": ">=8" } + }, + "node_modules/xml-formatter": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-3.6.3.tgz", + "integrity": "sha512-++x1TlRO1FRlQ82AZ4WnoCSufaI/PT/sycn4K8nRl4gnrNC1uYY2VV/67aALZ2m0Q4Q/BLj/L69K360Itw9NNg==", + "dependencies": { + "xml-parser-xo": "^4.1.2" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/xml-parser-xo": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-4.1.2.tgz", + "integrity": "sha512-Z/DRB0ZAKj5vAQg++XsfQQKfT73Vfj5n5lKIVXobBDQEva6NHWUTxOA6OohJmEcpoy8AEqBmSGkXXAnFwt5qAA==", + "engines": { + "node": ">= 16" + } } } } diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json index f6d3211cf..4d094a312 100644 --- a/plugins/exporter-curl/package-lock.json +++ b/plugins/exporter-curl/package-lock.json @@ -7,11 +7,12 @@ "": { "name": "exporter-curl", "version": "0.0.1", + "dependencies": { + "@yaakapp/api": "^0.1.6" + }, "devDependencies": { "@types/node": "^20.14.9", - "esbuild": "^0.21.5", "typescript": "^5.5.2", - "vite": "^5.3.2", "vitest": "^1.4.0" } }, @@ -699,6 +700,27 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@yaakapp/api": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", + "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "dependencies": { + "@types/node": "^22.0.0" + } + }, + "node_modules/@yaakapp/api/node_modules/@types/node": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz", + "integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==", + "dependencies": { + "undici-types": "~6.13.0" + } + }, + "node_modules/@yaakapp/api/node_modules/undici-types": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index 51bf7380c..fea70fea8 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -8,5 +8,8 @@ "@types/node": "^20.14.9", "typescript": "^5.5.2", "vitest": "^1.4.0" + }, + "dependencies": { + "@yaakapp/api": "^0.1.6" } } diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts index 44c99a1f8..faf338b27 100644 --- a/plugins/exporter-curl/src/index.ts +++ b/plugins/exporter-curl/src/index.ts @@ -1,8 +1,22 @@ -import { HttpRequest } from '../../../src-web/lib/models'; +import { HttpRequest, YaakContext, YaakPlugin } from '@yaakapp/api'; const NEWLINE = '\\\n '; -export function pluginHookExport(_: any, request: Partial) { +export const plugin: YaakPlugin = { + httpRequestActions: [{ + key: 'export-curl', + label: 'Copy as Curl', + icon: 'copy', + async onSelect(ctx, args) { + const rendered_request = await ctx.httpRequest.render({ httpRequest: args.httpRequest }); + const data = await pluginHookExport(ctx, rendered_request); + ctx.clipboard.copyText(data); + ctx.toast.show({ variant: 'copied', message: 'Curl copied to clipboard' }); + }, + }], +}; + +export async function pluginHookExport(_ctx: YaakContext, request: Partial) { const xs = ['curl']; // Add method and URL all on first line @@ -67,7 +81,7 @@ export function pluginHookExport(_: any, request: Partial) { } function quote(arg: string): string { - const escaped = arg.replace(/'/g, "\\'"); + const escaped = arg.replace(/'/g, '\\\''); return `'${escaped}'`; } diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index 64f9f06e8..377bc0e41 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -8,6 +8,7 @@ "name": "filter-jsonpath", "version": "0.0.1", "dependencies": { + "@yaakapp/api": "^0.1.6", "jsonpath": "^1.1.1" }, "devDependencies": { @@ -32,6 +33,27 @@ "undici-types": "~5.26.4" } }, + "node_modules/@yaakapp/api": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", + "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "dependencies": { + "@types/node": "^22.0.0" + } + }, + "node_modules/@yaakapp/api/node_modules/@types/node": { + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "dependencies": { + "undici-types": "~6.18.2" + } + }, + "node_modules/@yaakapp/api/node_modules/undici-types": { + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index fb4301949..b1a3a7b5a 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -5,7 +5,8 @@ "build": "cross-env BUILD_PLATFORM=browser yaakcli src/index.ts" }, "dependencies": { - "jsonpath": "^1.1.1" + "jsonpath": "^1.1.1", + "@yaakapp/api": "^0.1.6" }, "devDependencies": { "@types/jsonpath": "^0.2.4", diff --git a/plugins/filter-jsonpath/src/index.ts b/plugins/filter-jsonpath/src/index.ts index 7678d148b..609bd2628 100644 --- a/plugins/filter-jsonpath/src/index.ts +++ b/plugins/filter-jsonpath/src/index.ts @@ -1,6 +1,7 @@ +import { YaakContext } from '@yaakapp/api'; import jp from 'jsonpath'; -export function pluginHookResponseFilter(_ctx: any, args: { filter: string; body: string }) { +export function pluginHookResponseFilter(_ctx: YaakContext, args: { filter: string; body: string }) { const parsed = JSON.parse(args.body); const filtered = jp.query(parsed, args.filter); return JSON.stringify(filtered, null, 2); diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json index eaae4b96d..a53f4611e 100644 --- a/plugins/filter-xpath/package-lock.json +++ b/plugins/filter-xpath/package-lock.json @@ -10,595 +10,11 @@ "dependencies": { "@types/node": "^20.14.9", "@xmldom/xmldom": "^0.8.10", + "@yaakapp/api": "^0.1.6", "typescript": "^5.5.2", "xpath": "^0.0.34" - }, - "devDependencies": { - "vite": "^5.3.2" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", - "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", - "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", - "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", - "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", - "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", - "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", - "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", - "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", - "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", - "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", - "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", - "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", - "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", - "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", - "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", - "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, "node_modules/@types/node": { "version": "20.14.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", @@ -615,153 +31,26 @@ "node": ">=10.0.0" } }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/@yaakapp/api": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", + "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" + "@types/node": "^22.0.0" } }, - "node_modules/rollup": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", - "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", - "dev": true, + "node_modules/@yaakapp/api/node_modules/@types/node": { + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.0", - "@rollup/rollup-android-arm64": "4.18.0", - "@rollup/rollup-darwin-arm64": "4.18.0", - "@rollup/rollup-darwin-x64": "4.18.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", - "@rollup/rollup-linux-arm-musleabihf": "4.18.0", - "@rollup/rollup-linux-arm64-gnu": "4.18.0", - "@rollup/rollup-linux-arm64-musl": "4.18.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", - "@rollup/rollup-linux-riscv64-gnu": "4.18.0", - "@rollup/rollup-linux-s390x-gnu": "4.18.0", - "@rollup/rollup-linux-x64-gnu": "4.18.0", - "@rollup/rollup-linux-x64-musl": "4.18.0", - "@rollup/rollup-win32-arm64-msvc": "4.18.0", - "@rollup/rollup-win32-ia32-msvc": "4.18.0", - "@rollup/rollup-win32-x64-msvc": "4.18.0", - "fsevents": "~2.3.2" + "undici-types": "~6.18.2" } }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/@yaakapp/api/node_modules/undici-types": { + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, "node_modules/typescript": { "version": "5.5.2", @@ -780,61 +69,6 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, - "node_modules/vite": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", - "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", - "dev": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, "node_modules/xpath": { "version": "0.0.34", "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index 062ad1eee..d23fcff49 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -5,6 +5,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { + "@yaakapp/api": "^0.1.6", "@types/node": "^20.14.9", "@xmldom/xmldom": "^0.8.10", "typescript": "^5.5.2", diff --git a/plugins/filter-xpath/src/index.ts b/plugins/filter-xpath/src/index.ts index 35fd21de8..7d49d4a07 100644 --- a/plugins/filter-xpath/src/index.ts +++ b/plugins/filter-xpath/src/index.ts @@ -1,10 +1,17 @@ import { DOMParser } from '@xmldom/xmldom'; +import { YaakContext } from '@yaakapp/api'; import xpath from 'xpath'; export function pluginHookResponseFilter( - _ctx: any, + _ctx: YaakContext, { filter, body }: { filter: string; body: string }, ) { const doc = new DOMParser().parseFromString(body, 'text/xml'); - return `${xpath.select(filter, doc)}`; + const result = xpath.select(filter, doc, false); + if (Array.isArray(result)) { + return result.map(r => String(r)).join('\n'); + } else { + // Not sure what cases this happens in (?) + return String(result); + } } diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json index 468885344..9a7a99f49 100644 --- a/plugins/importer-curl/package-lock.json +++ b/plugins/importer-curl/package-lock.json @@ -8,13 +8,13 @@ "name": "importer-curl", "version": "0.0.1", "dependencies": { + "@yaakapp/api": "^0.1.6", "shell-quote": "^1.8.1" }, "devDependencies": { "@types/node": "^20.14.9", "@types/shell-quote": "^1.7.5", "typescript": "^5.5.2", - "vite": "^5.3.2", "vitest": "^1.4.0" } }, @@ -708,6 +708,27 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@yaakapp/api": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", + "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "dependencies": { + "@types/node": "^22.0.0" + } + }, + "node_modules/@yaakapp/api/node_modules/@types/node": { + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "dependencies": { + "undici-types": "~6.18.2" + } + }, + "node_modules/@yaakapp/api/node_modules/undici-types": { + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index a5eb5ca33..3582a31a1 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -5,6 +5,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { + "@yaakapp/api": "^0.1.6", "shell-quote": "^1.8.1" }, "devDependencies": { diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts index b6092b242..baf1c40d6 100644 --- a/plugins/importer-curl/src/index.ts +++ b/plugins/importer-curl/src/index.ts @@ -1,12 +1,5 @@ +import { Environment, Folder, HttpRequest, HttpUrlParameter, Model, Workspace, YaakContext } from '@yaakapp/api'; import { ControlOperator, parse, ParseEntry } from 'shell-quote'; -import { - Environment, - Folder, - HttpRequest, - HttpUrlParameter, - Model, - Workspace, -} from '../../../src-web/lib/models'; type AtLeast = Partial & Pick; @@ -39,7 +32,7 @@ type Pair = string | boolean; type PairsByName = Record; -export function pluginHookImport(_: any, rawData: string) { +export function pluginHookImport(ctx: YaakContext, rawData: string) { if (!rawData.match(/^\s*curl /)) { return null; } @@ -92,7 +85,7 @@ export function pluginHookImport(_: any, rawData: string) { if (op?.startsWith('$')) { // Handle the case where literal like -H $'Header: \'Some Quoted Thing\'' - const str = op.slice(2, op.length - 1).replace(/\\'/g, "'"); + const str = op.slice(2, op.length - 1).replace(/\\'/g, '\''); currentCommand.push(str); continue; @@ -192,9 +185,9 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { const authenticationType = username ? (isDigest ? 'digest' : 'basic') : null; const authentication = username ? { - username: username.trim(), - password: (password ?? '').trim(), - } + username: username.trim(), + password: (password ?? '').trim(), + } : {}; // Headers @@ -413,6 +406,7 @@ function splitOnce(str: string, sep: string): string[] { } const idCount: Partial> = {}; + function generateId(model: Model['model']): string { idCount[model] = (idCount[model] ?? -1) + 1; return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`; diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json index 80ec94825..5be33b77a 100644 --- a/plugins/importer-insomnia/package-lock.json +++ b/plugins/importer-insomnia/package-lock.json @@ -8,596 +8,14 @@ "name": "importer-insomnia", "version": "0.0.1", "dependencies": { + "@yaakapp/api": "^0.1.6", "yaml": "^2.4.2" }, "devDependencies": { "@types/node": "^20.14.9", - "typescript": "^5.5.2", - "vite": "^5.3.2" + "typescript": "^5.5.2" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", - "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", - "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", - "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", - "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", - "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", - "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", - "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", - "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", - "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", - "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", - "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", - "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", - "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", - "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", - "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", - "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, "node_modules/@types/node": { "version": "20.14.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", @@ -607,153 +25,26 @@ "undici-types": "~5.26.4" } }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/@yaakapp/api": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", + "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" + "@types/node": "^22.0.0" } }, - "node_modules/rollup": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", - "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", - "dev": true, + "node_modules/@yaakapp/api/node_modules/@types/node": { + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.0", - "@rollup/rollup-android-arm64": "4.18.0", - "@rollup/rollup-darwin-arm64": "4.18.0", - "@rollup/rollup-darwin-x64": "4.18.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", - "@rollup/rollup-linux-arm-musleabihf": "4.18.0", - "@rollup/rollup-linux-arm64-gnu": "4.18.0", - "@rollup/rollup-linux-arm64-musl": "4.18.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", - "@rollup/rollup-linux-riscv64-gnu": "4.18.0", - "@rollup/rollup-linux-s390x-gnu": "4.18.0", - "@rollup/rollup-linux-x64-gnu": "4.18.0", - "@rollup/rollup-linux-x64-musl": "4.18.0", - "@rollup/rollup-win32-arm64-msvc": "4.18.0", - "@rollup/rollup-win32-ia32-msvc": "4.18.0", - "@rollup/rollup-win32-x64-msvc": "4.18.0", - "fsevents": "~2.3.2" + "undici-types": "~6.18.2" } }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/@yaakapp/api/node_modules/undici-types": { + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, "node_modules/typescript": { "version": "5.5.2", @@ -774,61 +65,6 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, - "node_modules/vite": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", - "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", - "dev": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, "node_modules/yaml": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 02d57fe07..2d764fa3d 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -5,6 +5,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { + "@yaakapp/api": "^0.1.6", "yaml": "^2.4.2" }, "devDependencies": { diff --git a/plugins/importer-insomnia/src/index.ts b/plugins/importer-insomnia/src/index.ts index 11aa7faa3..8aa503773 100644 --- a/plugins/importer-insomnia/src/index.ts +++ b/plugins/importer-insomnia/src/index.ts @@ -1,10 +1,4 @@ -import { - Environment, - Folder, - GrpcRequest, - HttpRequest, - Workspace, -} from '../../../src-web/lib/models'; +import { Environment, Folder, GrpcRequest, HttpRequest, Workspace, YaakContext } from '@yaakapp/api'; import YAML from 'yaml'; type AtLeast = Partial & Pick; @@ -17,7 +11,7 @@ export interface ExportResources { folders: AtLeast[]; } -export function pluginHookImport(ctx: any, contents: string) { +export function pluginHookImport(ctx: YaakContext, contents: string) { let parsed: any; try { diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json index cdc308c98..017cbef28 100644 --- a/plugins/importer-openapi/package-lock.json +++ b/plugins/importer-openapi/package-lock.json @@ -1,13 +1,14 @@ { - "name": "importer-postman", + "name": "importer-openapi", "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "importer-postman", + "name": "importer-openapi", "version": "0.0.1", "dependencies": { + "@yaakapp/api": "^0.1.6", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, @@ -54,6 +55,27 @@ "@types/node": "*" } }, + "node_modules/@yaakapp/api": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", + "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "dependencies": { + "@types/node": "^22.0.0" + } + }, + "node_modules/@yaakapp/api/node_modules/@types/node": { + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "dependencies": { + "undici-types": "~6.18.2" + } + }, + "node_modules/@yaakapp/api/node_modules/undici-types": { + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + }, "node_modules/ajv": { "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index 2164487e6..3b2c5006d 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -5,6 +5,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { + "@yaakapp/api": "^0.1.6", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, diff --git a/plugins/importer-openapi/src/index.ts b/plugins/importer-openapi/src/index.ts index ee1cc66ff..39aedf43f 100644 --- a/plugins/importer-openapi/src/index.ts +++ b/plugins/importer-openapi/src/index.ts @@ -1,3 +1,4 @@ +import { YaakContext } from '@yaakapp/api'; import { convert } from 'openapi-to-postmanv2'; import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman/src/index'; import { Folder, HttpRequest, Workspace, Environment } from '../../../types/models'; @@ -12,13 +13,13 @@ interface ExportResources { } export async function pluginHookImport( - ctx: any, + ctx: YaakContext, contents: string, ): Promise<{ resources: ExportResources } | undefined> { let postmanCollection; try { postmanCollection = await new Promise((resolve, reject) => { - convert({ type: 'string', data: contents }, {}, (err, result) => { + convert({ type: 'string', data: contents }, {}, (err, result: any) => { if (err != null) reject(err); if (Array.isArray(result.output) && result.output.length > 0) { diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json index ff8ae5359..d768f6231 100644 --- a/plugins/importer-postman/package-lock.json +++ b/plugins/importer-postman/package-lock.json @@ -7,10 +7,13 @@ "": { "name": "importer-postman", "version": "0.0.1", + "dependencies": { + "@yaakapp/api": "^0.1.6" + }, "devDependencies": { "@types/node": "^20.14.9", + "esbuild": "^0.21.5", "typescript": "^5.5.2", - "vite": "^5.3.2", "vitest": "^1.4.0" } }, @@ -659,6 +662,27 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@yaakapp/api": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", + "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "dependencies": { + "@types/node": "^22.0.0" + } + }, + "node_modules/@yaakapp/api/node_modules/@types/node": { + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "dependencies": { + "undici-types": "~6.18.2" + } + }, + "node_modules/@yaakapp/api/node_modules/undici-types": { + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 995ec4183..1d2ed76c6 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -5,6 +5,9 @@ "scripts": { "build": "yaakcli ./src/index.js" }, + "dependencies": { + "@yaakapp/api": "^0.1.6" + }, "devDependencies": { "@types/node": "^20.14.9", "esbuild": "^0.21.5", diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts index a96ab7d98..3ab607c3e 100644 --- a/plugins/importer-postman/src/index.ts +++ b/plugins/importer-postman/src/index.ts @@ -1,5 +1,4 @@ -import { root } from 'postcss'; -import { Environment, Folder, HttpHeader, HttpRequest, Model, Workspace } from '../../../types/models'; +import { Environment, Folder, HttpRequest, HttpRequestHeader, Model, Workspace, YaakContext } from '@yaakapp/api'; const POSTMAN_2_1_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'; const POSTMAN_2_0_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json'; @@ -15,7 +14,7 @@ interface ExportResources { } export function pluginHookImport( - _ctx: any, + _ctx: YaakContext, contents: string, ): { resources: ExportResources } | undefined { const root = parseJSONToRecord(contents); @@ -68,7 +67,7 @@ export function pluginHookImport( const requestAuthPath = importAuth(r.auth); const authPatch = requestAuthPath.authenticationType == null ? globalAuth : requestAuthPath; - const headers: HttpHeader[] = toArray(r.header).map((h) => { + const headers: HttpRequestHeader[] = toArray(r.header).map((h) => { return { name: h.key, value: h.value, diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json index fccd4265a..e35abba9b 100644 --- a/plugins/importer-yaak/package-lock.json +++ b/plugins/importer-yaak/package-lock.json @@ -7,10 +7,13 @@ "": { "name": "importer-yaak", "version": "0.0.1", + "dependencies": { + "@yaakapp/api": "^0.1.6" + }, "devDependencies": { "@types/node": "^20.14.9", - "typescript": "^5.5.2", - "vite": "^5.3.2" + "esbuild": "^0.21.5", + "typescript": "^5.5.2" } }, "node_modules/@esbuild/aix-ppc64": { @@ -381,220 +384,6 @@ "node": ">=12" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", - "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", - "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", - "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", - "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", - "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", - "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", - "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", - "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", - "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", - "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", - "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", - "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", - "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", - "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", - "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", - "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, "node_modules/@types/node": { "version": "20.14.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", @@ -604,6 +393,27 @@ "undici-types": "~5.26.4" } }, + "node_modules/@yaakapp/api": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", + "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "dependencies": { + "@types/node": "^22.0.0" + } + }, + "node_modules/@yaakapp/api/node_modules/@types/node": { + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "dependencies": { + "undici-types": "~6.18.2" + } + }, + "node_modules/@yaakapp/api/node_modules/undici-types": { + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -642,116 +452,6 @@ "@esbuild/win32-x64": "0.21.5" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/rollup": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", - "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.0", - "@rollup/rollup-android-arm64": "4.18.0", - "@rollup/rollup-darwin-arm64": "4.18.0", - "@rollup/rollup-darwin-x64": "4.18.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", - "@rollup/rollup-linux-arm-musleabihf": "4.18.0", - "@rollup/rollup-linux-arm64-gnu": "4.18.0", - "@rollup/rollup-linux-arm64-musl": "4.18.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", - "@rollup/rollup-linux-riscv64-gnu": "4.18.0", - "@rollup/rollup-linux-s390x-gnu": "4.18.0", - "@rollup/rollup-linux-x64-gnu": "4.18.0", - "@rollup/rollup-linux-x64-musl": "4.18.0", - "@rollup/rollup-win32-arm64-msvc": "4.18.0", - "@rollup/rollup-win32-ia32-msvc": "4.18.0", - "@rollup/rollup-win32-x64-msvc": "4.18.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/typescript": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", @@ -770,61 +470,6 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true - }, - "node_modules/vite": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", - "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", - "dev": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } } } } diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index b8e4bc1df..ffec715f8 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -4,6 +4,9 @@ "scripts": { "build": "yaakcli ./src/index.js" }, + "dependencies": { + "@yaakapp/api": "^0.1.6" + }, "devDependencies": { "@types/node": "^20.14.9", "esbuild": "^0.21.5", diff --git a/plugins/importer-yaak/src/index.ts b/plugins/importer-yaak/src/index.ts index fc7daf58d..a26a2bc0d 100644 --- a/plugins/importer-yaak/src/index.ts +++ b/plugins/importer-yaak/src/index.ts @@ -1,4 +1,6 @@ -export function pluginHookImport(_ctx: any, contents: string) { +import { YaakContext } from '@yaakapp/api'; + +export function pluginHookImport(_ctx: YaakContext, contents: string) { let parsed; try { parsed = JSON.parse(contents); @@ -24,6 +26,6 @@ export function pluginHookImport(_ctx: any, contents: string) { return { resources: parsed.resources }; // Should already be in the correct format } -export function isJSObject(obj: any) { +function isJSObject(obj: any) { return Object.prototype.toString.call(obj) === '[object Object]'; } From d1871b19eecb0d4295231e2d6af9afdce8345ada Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 19 Aug 2024 19:11:36 -0700 Subject: [PATCH 019/996] Template response plugin --- package-lock.json | 191 +- package.json | 1 + plugins/exporter-curl/package-lock.json | 8 +- plugins/exporter-curl/package.json | 3 +- plugins/exporter-curl/src/index.ts | 6 +- plugins/filter-jsonpath/package-lock.json | 284 +-- plugins/filter-jsonpath/package.json | 9 +- plugins/filter-jsonpath/src/index.ts | 8 +- plugins/filter-xpath/package-lock.json | 19 +- plugins/filter-xpath/package.json | 9 +- plugins/filter-xpath/src/index.ts | 4 +- plugins/importer-curl/package-lock.json | 8 +- plugins/importer-curl/package.json | 3 +- plugins/importer-curl/src/index.ts | 4 +- plugins/importer-insomnia/package-lock.json | 8 +- plugins/importer-insomnia/package.json | 3 +- plugins/importer-insomnia/src/index.ts | 4 +- plugins/importer-openapi/package-lock.json | 8 +- plugins/importer-openapi/package.json | 3 +- plugins/importer-openapi/src/index.ts | 4 +- plugins/importer-postman/package-lock.json | 8 +- plugins/importer-postman/package.json | 3 +- plugins/importer-postman/src/index.ts | 4 +- plugins/importer-yaak/package-lock.json | 8 +- plugins/importer-yaak/package.json | 3 +- plugins/importer-yaak/src/index.ts | 4 +- .../package-lock.json | 1671 +++++++++++++++++ .../template-function-response/package.json | 20 + .../template-function-response/src/index.ts | 110 ++ .../tests/index.test.ts | 177 ++ 30 files changed, 2269 insertions(+), 326 deletions(-) create mode 100644 plugins/template-function-response/package-lock.json create mode 100644 plugins/template-function-response/package.json create mode 100644 plugins/template-function-response/src/index.ts create mode 100644 plugins/template-function-response/tests/index.test.ts diff --git a/package-lock.json b/package-lock.json index 79b5839e4..1a54adcda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,10 +5,8 @@ "packages": { "": { "name": "@yaakapp/plugins", - "dependencies": { - "xml-formatter": "^3.6.3" - }, "devDependencies": { + "jsonpath": "^1.1.1", "vitest": "^2.0.4" } }, @@ -819,6 +817,12 @@ "node": ">=6" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -857,6 +861,63 @@ "@esbuild/win32-x64": "0.21.5" } }, + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", @@ -866,6 +927,15 @@ "@types/estree": "^1.0.0" } }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -889,6 +959,12 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -951,6 +1027,30 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "dev": true, + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/loupe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", @@ -1053,6 +1153,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -1111,6 +1228,15 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/rollup": { "version": "4.19.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", @@ -1185,6 +1311,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -1200,6 +1336,15 @@ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "dev": true, + "dependencies": { + "escodegen": "^1.8.1" + } + }, "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", @@ -1251,6 +1396,24 @@ "node": ">=14.0.0" } }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, "node_modules/vite": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", @@ -1423,23 +1586,13 @@ "node": ">=8" } }, - "node_modules/xml-formatter": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-3.6.3.tgz", - "integrity": "sha512-++x1TlRO1FRlQ82AZ4WnoCSufaI/PT/sycn4K8nRl4gnrNC1uYY2VV/67aALZ2m0Q4Q/BLj/L69K360Itw9NNg==", - "dependencies": { - "xml-parser-xo": "^4.1.2" - }, - "engines": { - "node": ">= 16" - } - }, - "node_modules/xml-parser-xo": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-4.1.2.tgz", - "integrity": "sha512-Z/DRB0ZAKj5vAQg++XsfQQKfT73Vfj5n5lKIVXobBDQEva6NHWUTxOA6OohJmEcpoy8AEqBmSGkXXAnFwt5qAA==", + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, "engines": { - "node": ">= 16" + "node": ">=0.10.0" } } } diff --git a/package.json b/package.json index 64498c510..1288ed005 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "build": "node scripts/build-plugins.cjs" }, "devDependencies": { + "jsonpath": "^1.1.1", "vitest": "^2.0.4" } } diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json index 4d094a312..5a3b0fd82 100644 --- a/plugins/exporter-curl/package-lock.json +++ b/plugins/exporter-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "exporter-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.6" + "@yaakapp/api": "^0.1.9" }, "devDependencies": { "@types/node": "^20.14.9", @@ -701,9 +701,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", - "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", + "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index fea70fea8..ed9517403 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -1,5 +1,6 @@ { "name": "exporter-curl", + "private": true, "version": "0.0.1", "scripts": { "build": "yaakcli ./src/index.js" @@ -10,6 +11,6 @@ "vitest": "^1.4.0" }, "dependencies": { - "@yaakapp/api": "^0.1.6" + "@yaakapp/api": "^0.1.9" } } diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts index faf338b27..163c423f7 100644 --- a/plugins/exporter-curl/src/index.ts +++ b/plugins/exporter-curl/src/index.ts @@ -1,8 +1,8 @@ -import { HttpRequest, YaakContext, YaakPlugin } from '@yaakapp/api'; +import { Context, HttpRequest, Plugin } from '@yaakapp/api'; const NEWLINE = '\\\n '; -export const plugin: YaakPlugin = { +export const plugin: Plugin = { httpRequestActions: [{ key: 'export-curl', label: 'Copy as Curl', @@ -16,7 +16,7 @@ export const plugin: YaakPlugin = { }], }; -export async function pluginHookExport(_ctx: YaakContext, request: Partial) { +export async function pluginHookExport(_ctx: Context, request: Partial) { const xs = ['curl']; // Add method and URL all on first line diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index 377bc0e41..8dffe40d7 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -8,21 +8,35 @@ "name": "filter-jsonpath", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.6", - "jsonpath": "^1.1.1" + "@yaakapp/api": "^0.1.9", + "jsonpath-plus": "^9.0.0" }, "devDependencies": { - "@types/jsonpath": "^0.2.4", "@types/node": "^20.14.9", - "cross-env": "^7.0.3", "typescript": "^5.5.2" } }, - "node_modules/@types/jsonpath": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.4.tgz", - "integrity": "sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA==", - "dev": true + "node_modules/@jsep-plugin/assignment": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.2.1.tgz", + "integrity": "sha512-gaHqbubTi29aZpVbBlECRpmdia+L5/lh2BwtIJTmtxdbecEyyX/ejAOg7eQDGNvGOUmPY7Z2Yxdy9ioyH/VJeA==", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@jsep-plugin/regex": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", + "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } }, "node_modules/@types/node": { "version": "20.14.9", @@ -34,9 +48,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", - "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", + "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", "dependencies": { "@types/node": "^22.0.0" } @@ -54,217 +68,29 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, + "node_modules/jsep": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.9.tgz", + "integrity": "sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==", "engines": { - "node": ">= 8" + "node": ">= 10.16.0" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "node_modules/jsonpath-plus": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-9.0.0.tgz", + "integrity": "sha512-bqE77VIDStrOTV/czspZhTn+o27Xx9ZJRGVkdVShEtPoqsIx5yALv3lWVU6y+PqYvWPJNWE7ORCQheQkEe0DDA==", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" + "@jsep-plugin/assignment": "^1.2.1", + "@jsep-plugin/regex": "^1.0.3", + "jsep": "^1.3.8" }, "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" }, "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", - "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/jsonpath": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", - "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", - "dependencies": { - "esprima": "1.2.2", - "static-eval": "2.0.2", - "underscore": "1.12.1" - } - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-eval": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", - "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", - "dependencies": { - "escodegen": "^1.8.1" - } - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" + "node": ">=14.0.0" } }, "node_modules/typescript": { @@ -280,39 +106,11 @@ "node": ">=14.17" } }, - "node_modules/underscore": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", - "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "engines": { - "node": ">=0.10.0" - } } } } diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index b1a3a7b5a..cafa1603b 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -1,17 +1,16 @@ { "name": "filter-jsonpath", + "private": true, "version": "0.0.1", "scripts": { - "build": "cross-env BUILD_PLATFORM=browser yaakcli src/index.ts" + "build": "yaakcli src/index.ts" }, "dependencies": { - "jsonpath": "^1.1.1", - "@yaakapp/api": "^0.1.6" + "jsonpath-plus": "^9.0.0", + "@yaakapp/api": "^0.1.9" }, "devDependencies": { - "@types/jsonpath": "^0.2.4", "@types/node": "^20.14.9", - "cross-env": "^7.0.3", "typescript": "^5.5.2" } } diff --git a/plugins/filter-jsonpath/src/index.ts b/plugins/filter-jsonpath/src/index.ts index 609bd2628..2d2e71f57 100644 --- a/plugins/filter-jsonpath/src/index.ts +++ b/plugins/filter-jsonpath/src/index.ts @@ -1,8 +1,8 @@ -import { YaakContext } from '@yaakapp/api'; -import jp from 'jsonpath'; +import { Context } from '@yaakapp/api'; +import { JSONPath } from 'jsonpath-plus'; -export function pluginHookResponseFilter(_ctx: YaakContext, args: { filter: string; body: string }) { +export function pluginHookResponseFilter(_ctx: Context, args: { filter: string; body: string }) { const parsed = JSON.parse(args.body); - const filtered = jp.query(parsed, args.filter); + const filtered = JSONPath({ path: args.filter, json: parsed }); return JSON.stringify(filtered, null, 2); } diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json index a53f4611e..03503ec52 100644 --- a/plugins/filter-xpath/package-lock.json +++ b/plugins/filter-xpath/package-lock.json @@ -8,17 +8,20 @@ "name": "filter-xpath", "version": "0.0.1", "dependencies": { - "@types/node": "^20.14.9", "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.6", - "typescript": "^5.5.2", + "@yaakapp/api": "^0.1.9", "xpath": "^0.0.34" + }, + "devDependencies": { + "@types/node": "^20.14.9", + "typescript": "^5.5.2" } }, "node_modules/@types/node": { "version": "20.14.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -32,9 +35,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", - "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", + "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", "dependencies": { "@types/node": "^22.0.0" } @@ -56,6 +59,7 @@ "version": "5.5.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -67,7 +71,8 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "node_modules/xpath": { "version": "0.0.34", diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index d23fcff49..34cb22bc5 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -1,14 +1,17 @@ { "name": "filter-xpath", + "private": true, "version": "0.0.1", "scripts": { "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.6", - "@types/node": "^20.14.9", + "@yaakapp/api": "^0.1.9", "@xmldom/xmldom": "^0.8.10", - "typescript": "^5.5.2", "xpath": "^0.0.34" + }, + "devDependencies": { + "@types/node": "^20.14.9", + "typescript": "^5.5.2" } } diff --git a/plugins/filter-xpath/src/index.ts b/plugins/filter-xpath/src/index.ts index 7d49d4a07..bd7f61c64 100644 --- a/plugins/filter-xpath/src/index.ts +++ b/plugins/filter-xpath/src/index.ts @@ -1,9 +1,9 @@ import { DOMParser } from '@xmldom/xmldom'; -import { YaakContext } from '@yaakapp/api'; +import { Context } from '@yaakapp/api'; import xpath from 'xpath'; export function pluginHookResponseFilter( - _ctx: YaakContext, + _ctx: Context, { filter, body }: { filter: string; body: string }, ) { const doc = new DOMParser().parseFromString(body, 'text/xml'); diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json index 9a7a99f49..82298cd8d 100644 --- a/plugins/importer-curl/package-lock.json +++ b/plugins/importer-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.6", + "@yaakapp/api": "^0.1.9", "shell-quote": "^1.8.1" }, "devDependencies": { @@ -709,9 +709,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", - "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", + "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index 3582a31a1..3d7330809 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -1,11 +1,12 @@ { "name": "importer-curl", + "private": true, "version": "0.0.1", "scripts": { "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.6", + "@yaakapp/api": "^0.1.9", "shell-quote": "^1.8.1" }, "devDependencies": { diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts index baf1c40d6..888f39b1f 100644 --- a/plugins/importer-curl/src/index.ts +++ b/plugins/importer-curl/src/index.ts @@ -1,4 +1,4 @@ -import { Environment, Folder, HttpRequest, HttpUrlParameter, Model, Workspace, YaakContext } from '@yaakapp/api'; +import { Environment, Folder, HttpRequest, HttpUrlParameter, Model, Workspace, Context } from '@yaakapp/api'; import { ControlOperator, parse, ParseEntry } from 'shell-quote'; type AtLeast = Partial & Pick; @@ -32,7 +32,7 @@ type Pair = string | boolean; type PairsByName = Record; -export function pluginHookImport(ctx: YaakContext, rawData: string) { +export function pluginHookImport(ctx: Context, rawData: string) { if (!rawData.match(/^\s*curl /)) { return null; } diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json index 5be33b77a..5ce31d167 100644 --- a/plugins/importer-insomnia/package-lock.json +++ b/plugins/importer-insomnia/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-insomnia", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.6", + "@yaakapp/api": "^0.1.9", "yaml": "^2.4.2" }, "devDependencies": { @@ -26,9 +26,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", - "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", + "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 2d764fa3d..0369d725f 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -1,11 +1,12 @@ { "name": "importer-insomnia", + "private": true, "version": "0.0.1", "scripts": { "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.6", + "@yaakapp/api": "^0.1.9", "yaml": "^2.4.2" }, "devDependencies": { diff --git a/plugins/importer-insomnia/src/index.ts b/plugins/importer-insomnia/src/index.ts index 8aa503773..9f320b593 100644 --- a/plugins/importer-insomnia/src/index.ts +++ b/plugins/importer-insomnia/src/index.ts @@ -1,4 +1,4 @@ -import { Environment, Folder, GrpcRequest, HttpRequest, Workspace, YaakContext } from '@yaakapp/api'; +import { Environment, Folder, GrpcRequest, HttpRequest, Workspace, Context } from '@yaakapp/api'; import YAML from 'yaml'; type AtLeast = Partial & Pick; @@ -11,7 +11,7 @@ export interface ExportResources { folders: AtLeast[]; } -export function pluginHookImport(ctx: YaakContext, contents: string) { +export function pluginHookImport(ctx: Context, contents: string) { let parsed: any; try { diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json index 017cbef28..b7c5e579e 100644 --- a/plugins/importer-openapi/package-lock.json +++ b/plugins/importer-openapi/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-openapi", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.6", + "@yaakapp/api": "^0.1.9", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, @@ -56,9 +56,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", - "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", + "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index 3b2c5006d..515019a7a 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -1,11 +1,12 @@ { "name": "importer-openapi", + "private": true, "version": "0.0.1", "scripts": { "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.6", + "@yaakapp/api": "^0.1.9", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, diff --git a/plugins/importer-openapi/src/index.ts b/plugins/importer-openapi/src/index.ts index 39aedf43f..782bd24bc 100644 --- a/plugins/importer-openapi/src/index.ts +++ b/plugins/importer-openapi/src/index.ts @@ -1,4 +1,4 @@ -import { YaakContext } from '@yaakapp/api'; +import { Context } from '@yaakapp/api'; import { convert } from 'openapi-to-postmanv2'; import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman/src/index'; import { Folder, HttpRequest, Workspace, Environment } from '../../../types/models'; @@ -13,7 +13,7 @@ interface ExportResources { } export async function pluginHookImport( - ctx: YaakContext, + ctx: Context, contents: string, ): Promise<{ resources: ExportResources } | undefined> { let postmanCollection; diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json index d768f6231..3a290e033 100644 --- a/plugins/importer-postman/package-lock.json +++ b/plugins/importer-postman/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-postman", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.6" + "@yaakapp/api": "^0.1.9" }, "devDependencies": { "@types/node": "^20.14.9", @@ -663,9 +663,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", - "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", + "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 1d2ed76c6..693a9d700 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -1,12 +1,13 @@ { "name": "importer-postman", + "private": true, "version": "0.0.1", "main": "./build/index.js", "scripts": { "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.6" + "@yaakapp/api": "^0.1.9" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts index 3ab607c3e..3ab59a55c 100644 --- a/plugins/importer-postman/src/index.ts +++ b/plugins/importer-postman/src/index.ts @@ -1,4 +1,4 @@ -import { Environment, Folder, HttpRequest, HttpRequestHeader, Model, Workspace, YaakContext } from '@yaakapp/api'; +import { Environment, Folder, HttpRequest, HttpRequestHeader, Model, Workspace, Context } from '@yaakapp/api'; const POSTMAN_2_1_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'; const POSTMAN_2_0_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json'; @@ -14,7 +14,7 @@ interface ExportResources { } export function pluginHookImport( - _ctx: YaakContext, + _ctx: Context, contents: string, ): { resources: ExportResources } | undefined { const root = parseJSONToRecord(contents); diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json index e35abba9b..bbb325048 100644 --- a/plugins/importer-yaak/package-lock.json +++ b/plugins/importer-yaak/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-yaak", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.6" + "@yaakapp/api": "^0.1.9" }, "devDependencies": { "@types/node": "^20.14.9", @@ -394,9 +394,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz", - "integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", + "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index ffec715f8..6724d9077 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -1,11 +1,12 @@ { "name": "importer-yaak", + "private": true, "version": "0.0.1", "scripts": { "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.6" + "@yaakapp/api": "^0.1.9" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/importer-yaak/src/index.ts b/plugins/importer-yaak/src/index.ts index a26a2bc0d..8e53dd4de 100644 --- a/plugins/importer-yaak/src/index.ts +++ b/plugins/importer-yaak/src/index.ts @@ -1,6 +1,6 @@ -import { YaakContext } from '@yaakapp/api'; +import { Context } from '@yaakapp/api'; -export function pluginHookImport(_ctx: YaakContext, contents: string) { +export function pluginHookImport(_ctx: Context, contents: string) { let parsed; try { parsed = JSON.parse(contents); diff --git a/plugins/template-function-response/package-lock.json b/plugins/template-function-response/package-lock.json new file mode 100644 index 000000000..e6e882a9a --- /dev/null +++ b/plugins/template-function-response/package-lock.json @@ -0,0 +1,1671 @@ +{ + "name": "template-function-response", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "template-function-response", + "version": "0.0.1", + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "@yaakapp/api": "^0.1.9", + "jsonpath-plus": "^9.0.0", + "xpath": "^0.0.34" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4", + "@types/node": "^20.14.9", + "typescript": "^5.5.2", + "vitest": "^1.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jsep-plugin/assignment": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.2.1.tgz", + "integrity": "sha512-gaHqbubTi29aZpVbBlECRpmdia+L5/lh2BwtIJTmtxdbecEyyX/ejAOg7eQDGNvGOUmPY7Z2Yxdy9ioyH/VJeA==", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@jsep-plugin/regex": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", + "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", + "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", + "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", + "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", + "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", + "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", + "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", + "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", + "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", + "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", + "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", + "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", + "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", + "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", + "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", + "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", + "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/jsonpath": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.4.tgz", + "integrity": "sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@vitest/expect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.6.0", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@yaakapp/api": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", + "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", + "dependencies": { + "@types/node": "^22.0.0" + } + }, + "node_modules/@yaakapp/api/node_modules/@types/node": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz", + "integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==", + "dependencies": { + "undici-types": "~6.13.0" + } + }, + "node_modules/@yaakapp/api/node_modules/undici-types": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", + "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", + "dev": true + }, + "node_modules/jsep": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.9.tgz", + "integrity": "sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==", + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/jsonpath-plus": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-9.0.0.tgz", + "integrity": "sha512-bqE77VIDStrOTV/czspZhTn+o27Xx9ZJRGVkdVShEtPoqsIx5yALv3lWVU6y+PqYvWPJNWE7ORCQheQkEe0DDA==", + "dependencies": { + "@jsep-plugin/assignment": "^1.2.1", + "@jsep-plugin/regex": "^1.0.3", + "jsep": "^1.3.8" + }, + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mlly": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.0.tgz", + "integrity": "sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.0", + "ufo": "^1.5.3" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/pkg-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz", + "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==", + "dev": true, + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.6.1", + "pathe": "^1.1.2" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/rollup": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", + "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.17.2", + "@rollup/rollup-android-arm64": "4.17.2", + "@rollup/rollup-darwin-arm64": "4.17.2", + "@rollup/rollup-darwin-x64": "4.17.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", + "@rollup/rollup-linux-arm-musleabihf": "4.17.2", + "@rollup/rollup-linux-arm64-gnu": "4.17.2", + "@rollup/rollup-linux-arm64-musl": "4.17.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", + "@rollup/rollup-linux-riscv64-gnu": "4.17.2", + "@rollup/rollup-linux-s390x-gnu": "4.17.2", + "@rollup/rollup-linux-x64-gnu": "4.17.2", + "@rollup/rollup-linux-x64-musl": "4.17.2", + "@rollup/rollup-win32-arm64-msvc": "4.17.2", + "@rollup/rollup-win32-ia32-msvc": "4.17.2", + "@rollup/rollup-win32-x64-msvc": "4.17.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", + "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", + "dev": true, + "dependencies": { + "js-tokens": "^9.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/tinybench": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", + "dev": true + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/vite": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", + "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.6.0", + "@vitest/runner": "1.6.0", + "@vitest/snapshot": "1.6.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.0", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.0", + "@vitest/ui": "1.6.0", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/xpath": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", + "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==", + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/plugins/template-function-response/package.json b/plugins/template-function-response/package.json new file mode 100644 index 000000000..06d4c93b5 --- /dev/null +++ b/plugins/template-function-response/package.json @@ -0,0 +1,20 @@ +{ + "name": "template-function-response", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli src/index.ts" + }, + "dependencies": { + "@yaakapp/api": "^0.1.9", + "jsonpath-plus": "^9.0.0", + "xpath": "^0.0.34", + "@xmldom/xmldom": "^0.8.10" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4", + "@types/node": "^20.14.9", + "typescript": "^5.5.2", + "vitest": "^1.4.0" + } +} diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts new file mode 100644 index 000000000..41968c642 --- /dev/null +++ b/plugins/template-function-response/src/index.ts @@ -0,0 +1,110 @@ +import { DOMParser } from '@xmldom/xmldom'; +import { CallTemplateFunctionArgs, Context, Plugin } from '@yaakapp/api'; +import { JSONPath } from 'jsonpath-plus'; +import { readFileSync } from 'node:fs'; +import xpath from 'xpath'; + +export const plugin: Plugin = { + templateFunctions: [{ + name: 'Response', + args: [ + { + type: 'http_request', + name: 'request', + label: 'Request', + }, + { + type: 'text', + name: 'path', + label: 'JSONPath or XPath', + placeholder: '$.books[0].id or /books[0]/id' + }, + { + type: 'select', + name: 'behavior', + label: 'Sending Behavior', + defaultValue: 'smart', + options: [ + { name: 'When no responses', value: 'smart' }, + { name: 'Always', value: 'always' }, + { name: 'Never', value: 'never' }, + ], + }, + ], + async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { + if (!args.values.request || !args.values.path) { + return null; + } + + const httpRequest = await ctx.httpRequest.getById({ id: args.values.request ?? 'n/a' }); + if (httpRequest == null) { + return null; + } + const renderedHttpRequest = await ctx.httpRequest.render({ httpRequest }); + + const responses = await ctx.httpResponse.find({ requestId: httpRequest.id, limit: 1 }); + + if (args.values.behavior === 'never' && responses.length === 0) { + return null; + } + + const response = (args.values.behavior === 'always' || responses[0] == null) + ? await ctx.httpRequest.send({ httpRequest: renderedHttpRequest }) + : responses[0]; + + if (response.bodyPath == null) { + return null; + } + + let body; + try { + body = readFileSync(response.bodyPath, 'utf-8'); + } catch (_) { + return null; + } + + try { + return filterJSONPath(body, args.values.path); + } catch (err) { + // Probably not JSON, try XPath + } + + try { + return filterXPath(body, args.values.path); + } catch (err) { + // Probably not XML + } + + return null; // Bail out + }, + }], +}; + +function filterJSONPath(body: string, path: string): string { + const parsed = JSON.parse(body); + const items = JSONPath({ path, json: parsed })[0]; + if (items == null) { + return ''; + } + + if ( + Object.prototype.toString.call(items) === '[object Array]' || + Object.prototype.toString.call(items) === '[object Object]' + ) { + return JSON.stringify(items); + } else { + return String(items); + } +} + +function filterXPath(body: string, path: string): string { + const doc = new DOMParser().parseFromString(body, 'text/xml'); + const items = xpath.select(path, doc, false); + + if (Array.isArray(items)) { + return String(items[0] ?? ''); + } else { + // Not sure what cases this happens in (?) + return String(items); + } +} diff --git a/plugins/template-function-response/tests/index.test.ts b/plugins/template-function-response/tests/index.test.ts new file mode 100644 index 000000000..caceb95fb --- /dev/null +++ b/plugins/template-function-response/tests/index.test.ts @@ -0,0 +1,177 @@ +import { describe, expect, test } from 'vitest'; +import { pluginHookExport } from '../src'; + +const ctx = {}; + +describe('exporter-curl', () => { + test('Exports GET with params', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + urlParameters: [ + { name: 'a', value: 'aaa' }, + { name: 'b', value: 'bbb', enabled: true }, + { name: 'c', value: 'ccc', enabled: false }, + ], + }), + ).toEqual( + [`curl 'https://yaak.app'`, `--url-query 'a=aaa'`, `--url-query 'b=bbb'`].join(` \\\n `), + ); + }); + test('Exports POST with url form data', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + method: 'POST', + bodyType: 'application/x-www-form-urlencoded', + body: { + form: [ + { name: 'a', value: 'aaa' }, + { name: 'b', value: 'bbb', enabled: true }, + { name: 'c', value: 'ccc', enabled: false }, + ], + }, + }), + ).toEqual( + [`curl -X POST 'https://yaak.app'`, `--data 'a=aaa'`, `--data 'b=bbb'`].join(` \\\n `), + ); + }); + + test('Exports PUT with multipart form', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + method: 'PUT', + bodyType: 'multipart/form-data', + body: { + form: [ + { name: 'a', value: 'aaa' }, + { name: 'b', value: 'bbb', enabled: true }, + { name: 'c', value: 'ccc', enabled: false }, + { name: 'f', file: '/foo/bar.png', contentType: 'image/png' }, + ], + }, + }), + ).toEqual( + [ + `curl -X PUT 'https://yaak.app'`, + `--form 'a=aaa'`, + `--form 'b=bbb'`, + `--form f=@/foo/bar.png;type=image/png`, + ].join(` \\\n `), + ); + }); + + test('Exports JSON body', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + method: 'POST', + bodyType: 'application/json', + body: { + text: `{"foo":"bar's"}`, + }, + headers: [{ name: 'Content-Type', value: 'application/json' }], + }), + ).toEqual( + [ + `curl -X POST 'https://yaak.app'`, + `--header 'Content-Type: application/json'`, + `--data-raw $'{"foo":"bar\\'s"}'`, + ].join(` \\\n `), + ); + }); + + test('Exports multi-line JSON body', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + method: 'POST', + bodyType: 'application/json', + body: { + text: `{"foo":"bar",\n"baz":"qux"}`, + }, + headers: [{ name: 'Content-Type', value: 'application/json' }], + }), + ).toEqual( + [ + `curl -X POST 'https://yaak.app'`, + `--header 'Content-Type: application/json'`, + `--data-raw $'{"foo":"bar",\n"baz":"qux"}'`, + ].join(` \\\n `), + ); + }); + + test('Exports headers', () => { + expect( + pluginHookExport(ctx, { + headers: [ + { name: 'a', value: 'aaa' }, + { name: 'b', value: 'bbb', enabled: true }, + { name: 'c', value: 'ccc', enabled: false }, + ], + }), + ).toEqual([`curl`, `--header 'a: aaa'`, `--header 'b: bbb'`].join(` \\\n `)); + }); + + test('Basic auth', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + authenticationType: 'basic', + authentication: { + username: 'user', + password: 'pass', + }, + }), + ).toEqual([`curl 'https://yaak.app'`, `--user 'user:pass'`].join(` \\\n `)); + }); + + test('Broken basic auth', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + authenticationType: 'basic', + authentication: {}, + }), + ).toEqual([`curl 'https://yaak.app'`, `--user ':'`].join(` \\\n `)); + }); + + test('Digest auth', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + authenticationType: 'digest', + authentication: { + username: 'user', + password: 'pass', + }, + }), + ).toEqual([`curl 'https://yaak.app'`, `--digest --user 'user:pass'`].join(` \\\n `)); + }); + + test('Bearer auth', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + authenticationType: 'bearer', + authentication: { + token: 'tok', + }, + }), + ).toEqual([`curl 'https://yaak.app'`, `--header 'Authorization: Bearer tok'`].join(` \\\n `)); + }); + + test('Broken bearer auth', () => { + expect( + pluginHookExport(ctx, { + url: 'https://yaak.app', + authenticationType: 'bearer', + authentication: { + username: 'user', + password: 'pass', + }, + }), + ).toEqual([`curl 'https://yaak.app'`, `--header 'Authorization: Bearer '`].join(` \\\n `)); + }); +}); From 5ba11ca78819885fc41123f18c7fff3d10c29fb5 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 22 Aug 2024 11:27:57 -0700 Subject: [PATCH 020/996] Bump plugin deps --- plugins/exporter-curl/package-lock.json | 8 +++---- plugins/exporter-curl/package.json | 2 +- plugins/filter-jsonpath/package-lock.json | 8 +++---- plugins/filter-jsonpath/package.json | 2 +- plugins/filter-xpath/package-lock.json | 8 +++---- plugins/filter-xpath/package.json | 2 +- plugins/importer-curl/package-lock.json | 8 +++---- plugins/importer-curl/package.json | 2 +- plugins/importer-insomnia/package-lock.json | 8 +++---- plugins/importer-insomnia/package.json | 2 +- plugins/importer-openapi/package-lock.json | 8 +++---- plugins/importer-openapi/package.json | 2 +- plugins/importer-postman/package-lock.json | 8 +++---- plugins/importer-postman/package.json | 2 +- plugins/importer-yaak/package-lock.json | 8 +++---- plugins/importer-yaak/package.json | 2 +- .../package-lock.json | 8 +++---- .../template-function-response/package.json | 2 +- .../template-function-response/src/index.ts | 23 ++++++++++++++----- scripts/build-plugins.cjs | 8 +++---- 20 files changed, 66 insertions(+), 55 deletions(-) diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json index 5a3b0fd82..673b3e0fa 100644 --- a/plugins/exporter-curl/package-lock.json +++ b/plugins/exporter-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "exporter-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.9" + "@yaakapp/api": "^0.1.11" }, "devDependencies": { "@types/node": "^20.14.9", @@ -701,9 +701,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", - "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", + "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index ed9517403..b4c5f94bb 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -11,6 +11,6 @@ "vitest": "^1.4.0" }, "dependencies": { - "@yaakapp/api": "^0.1.9" + "@yaakapp/api": "^0.1.11" } } diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index 8dffe40d7..5de500987 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -8,7 +8,7 @@ "name": "filter-jsonpath", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "jsonpath-plus": "^9.0.0" }, "devDependencies": { @@ -48,9 +48,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", - "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", + "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index cafa1603b..fe6d9d9dd 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "jsonpath-plus": "^9.0.0", - "@yaakapp/api": "^0.1.9" + "@yaakapp/api": "^0.1.11" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json index 03503ec52..64394d487 100644 --- a/plugins/filter-xpath/package-lock.json +++ b/plugins/filter-xpath/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "xpath": "^0.0.34" }, "devDependencies": { @@ -35,9 +35,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", - "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", + "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index 34cb22bc5..c9dc6e00f 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "@xmldom/xmldom": "^0.8.10", "xpath": "^0.0.34" }, diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json index 82298cd8d..9be007cdf 100644 --- a/plugins/importer-curl/package-lock.json +++ b/plugins/importer-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "shell-quote": "^1.8.1" }, "devDependencies": { @@ -709,9 +709,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", - "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", + "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index 3d7330809..91e2bc4af 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "shell-quote": "^1.8.1" }, "devDependencies": { diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json index 5ce31d167..29c440116 100644 --- a/plugins/importer-insomnia/package-lock.json +++ b/plugins/importer-insomnia/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-insomnia", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "yaml": "^2.4.2" }, "devDependencies": { @@ -26,9 +26,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", - "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", + "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 0369d725f..4eed9cca1 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "yaml": "^2.4.2" }, "devDependencies": { diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json index b7c5e579e..7fe8b9d59 100644 --- a/plugins/importer-openapi/package-lock.json +++ b/plugins/importer-openapi/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-openapi", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, @@ -56,9 +56,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", - "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", + "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index 515019a7a..355c9cb3f 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json index 3a290e033..29c684663 100644 --- a/plugins/importer-postman/package-lock.json +++ b/plugins/importer-postman/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-postman", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.9" + "@yaakapp/api": "^0.1.11" }, "devDependencies": { "@types/node": "^20.14.9", @@ -663,9 +663,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", - "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", + "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 693a9d700..bf5b89cb8 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -7,7 +7,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.9" + "@yaakapp/api": "^0.1.11" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json index bbb325048..f96ee6090 100644 --- a/plugins/importer-yaak/package-lock.json +++ b/plugins/importer-yaak/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-yaak", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.9" + "@yaakapp/api": "^0.1.11" }, "devDependencies": { "@types/node": "^20.14.9", @@ -394,9 +394,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", - "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", + "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index 6724d9077..ea6ab6cb9 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.9" + "@yaakapp/api": "^0.1.11" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/template-function-response/package-lock.json b/plugins/template-function-response/package-lock.json index e6e882a9a..3d64a872c 100644 --- a/plugins/template-function-response/package-lock.json +++ b/plugins/template-function-response/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34" }, @@ -741,9 +741,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.9.tgz", - "integrity": "sha512-5mgBoNplXUnNIUpLgGPCjcf6p/BcsU485cH3/MnIzcXIaMfFpZVVwHq5vf9cm+NDcr5hwYmPyIbwmBf9uVoV2Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", + "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/template-function-response/package.json b/plugins/template-function-response/package.json index 06d4c93b5..b81478609 100644 --- a/plugins/template-function-response/package.json +++ b/plugins/template-function-response/package.json @@ -6,7 +6,7 @@ "build": "yaakcli src/index.ts" }, "dependencies": { - "@yaakapp/api": "^0.1.9", + "@yaakapp/api": "^0.1.11", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34", "@xmldom/xmldom": "^0.8.10" diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts index 41968c642..966e23e95 100644 --- a/plugins/template-function-response/src/index.ts +++ b/plugins/template-function-response/src/index.ts @@ -1,5 +1,5 @@ import { DOMParser } from '@xmldom/xmldom'; -import { CallTemplateFunctionArgs, Context, Plugin } from '@yaakapp/api'; +import { CallTemplateFunctionArgs, Context, HttpResponse, Plugin } from '@yaakapp/api'; import { JSONPath } from 'jsonpath-plus'; import { readFileSync } from 'node:fs'; import xpath from 'xpath'; @@ -17,7 +17,7 @@ export const plugin: Plugin = { type: 'text', name: 'path', label: 'JSONPath or XPath', - placeholder: '$.books[0].id or /books[0]/id' + placeholder: '$.books[0].id or /books[0]/id', }, { type: 'select', @@ -48,9 +48,20 @@ export const plugin: Plugin = { return null; } - const response = (args.values.behavior === 'always' || responses[0] == null) - ? await ctx.httpRequest.send({ httpRequest: renderedHttpRequest }) - : responses[0]; + let response: HttpResponse | null = responses[0] ?? null; + + // Previews happen a ton, and we don't want to send too many times on "always," so treat + // it as "smart" during preview. + let behavior = args.values.behavior === 'always' && args.purpose === 'preview' ? 'smart' : args.values.behavior; + + // Send if no responses and "smart," or "always" + if ((behavior === 'smart' && response == null) || behavior === 'always') { + response = await ctx.httpRequest.send({ httpRequest: renderedHttpRequest }); + } + + if (response == null) { + return null; + } if (response.bodyPath == null) { return null; @@ -102,7 +113,7 @@ function filterXPath(body: string, path: string): string { const items = xpath.select(path, doc, false); if (Array.isArray(items)) { - return String(items[0] ?? ''); + return items[0] != null ? String(items[0].firstChild ?? '') : ''; } else { // Not sure what cases this happens in (?) return String(items); diff --git a/scripts/build-plugins.cjs b/scripts/build-plugins.cjs index 2e617472c..687fc73cd 100644 --- a/scripts/build-plugins.cjs +++ b/scripts/build-plugins.cjs @@ -1,5 +1,5 @@ -const {readdirSync, readFileSync} = require('node:fs'); -const {execSync} = require('node:child_process'); +const { readdirSync, readFileSync } = require('node:fs'); +const { execSync } = require('node:child_process'); const path = require('node:path'); async function main() { @@ -13,8 +13,8 @@ async function main() { const pkg = JSON.parse(readFileSync(path.join(pluginDir, 'package.json'), 'utf8')); console.log('Building plugin', pkg.name, pluginDir); - execSync(`npm ci`, {cwd: pluginDir}); - execSync(`npm run build`, {cwd: pluginDir}); + execSync(`npm install`, { cwd: pluginDir }); + execSync(`npm run build`, { cwd: pluginDir }); } } From 7ca3b9bd20ec9fa6c3fc03170ee4a42a7b755c63 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 23 Aug 2024 13:31:39 -0700 Subject: [PATCH 021/996] Send purpose with render request --- plugins/exporter-curl/package-lock.json | 8 ++++---- plugins/exporter-curl/package.json | 2 +- plugins/exporter-curl/src/index.ts | 2 +- plugins/filter-jsonpath/package-lock.json | 8 ++++---- plugins/filter-jsonpath/package.json | 2 +- plugins/filter-xpath/package-lock.json | 8 ++++---- plugins/filter-xpath/package.json | 2 +- plugins/importer-curl/package-lock.json | 8 ++++---- plugins/importer-curl/package.json | 2 +- plugins/importer-curl/src/index.ts | 2 +- plugins/importer-insomnia/package-lock.json | 8 ++++---- plugins/importer-insomnia/package.json | 2 +- plugins/importer-openapi/package-lock.json | 8 ++++---- plugins/importer-openapi/package.json | 2 +- plugins/importer-postman/package-lock.json | 8 ++++---- plugins/importer-postman/package.json | 2 +- plugins/importer-yaak/package-lock.json | 8 ++++---- plugins/importer-yaak/package.json | 2 +- plugins/template-function-response/package-lock.json | 8 ++++---- plugins/template-function-response/package.json | 2 +- 20 files changed, 47 insertions(+), 47 deletions(-) diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json index 673b3e0fa..50e01ba04 100644 --- a/plugins/exporter-curl/package-lock.json +++ b/plugins/exporter-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "exporter-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.11" + "@yaakapp/api": "^0.1.12" }, "devDependencies": { "@types/node": "^20.14.9", @@ -701,9 +701,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", - "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", + "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index b4c5f94bb..28a892541 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -11,6 +11,6 @@ "vitest": "^1.4.0" }, "dependencies": { - "@yaakapp/api": "^0.1.11" + "@yaakapp/api": "^0.1.12" } } diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts index 163c423f7..a87da82e7 100644 --- a/plugins/exporter-curl/src/index.ts +++ b/plugins/exporter-curl/src/index.ts @@ -8,7 +8,7 @@ export const plugin: Plugin = { label: 'Copy as Curl', icon: 'copy', async onSelect(ctx, args) { - const rendered_request = await ctx.httpRequest.render({ httpRequest: args.httpRequest }); + const rendered_request = await ctx.httpRequest.render({ httpRequest: args.httpRequest, purpose: 'preview' }); const data = await pluginHookExport(ctx, rendered_request); ctx.clipboard.copyText(data); ctx.toast.show({ variant: 'copied', message: 'Curl copied to clipboard' }); diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index 5de500987..63e535b48 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -8,7 +8,7 @@ "name": "filter-jsonpath", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "jsonpath-plus": "^9.0.0" }, "devDependencies": { @@ -48,9 +48,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", - "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", + "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index fe6d9d9dd..4e28707c5 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "jsonpath-plus": "^9.0.0", - "@yaakapp/api": "^0.1.11" + "@yaakapp/api": "^0.1.12" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json index 64394d487..6afa3055f 100644 --- a/plugins/filter-xpath/package-lock.json +++ b/plugins/filter-xpath/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "xpath": "^0.0.34" }, "devDependencies": { @@ -35,9 +35,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", - "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", + "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index c9dc6e00f..98f517ce0 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "@xmldom/xmldom": "^0.8.10", "xpath": "^0.0.34" }, diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json index 9be007cdf..94edb0a77 100644 --- a/plugins/importer-curl/package-lock.json +++ b/plugins/importer-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "shell-quote": "^1.8.1" }, "devDependencies": { @@ -709,9 +709,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", - "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", + "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index 91e2bc4af..e80877dbb 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "shell-quote": "^1.8.1" }, "devDependencies": { diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts index 888f39b1f..87b6f40e7 100644 --- a/plugins/importer-curl/src/index.ts +++ b/plugins/importer-curl/src/index.ts @@ -173,7 +173,7 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { urlParameters = search?.split('&').map((p) => { const v = splitOnce(p, '='); - return { name: v[0] ?? '', value: v[1] ?? '', enabled: true }; + return { name: decodeURIComponent(v[0] ?? ''), value: decodeURIComponent(v[1] ?? ''), enabled: true }; }) ?? []; url = baseUrl ?? urlArg; diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json index 29c440116..bbb49edab 100644 --- a/plugins/importer-insomnia/package-lock.json +++ b/plugins/importer-insomnia/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-insomnia", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "yaml": "^2.4.2" }, "devDependencies": { @@ -26,9 +26,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", - "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", + "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 4eed9cca1..394a1def8 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "yaml": "^2.4.2" }, "devDependencies": { diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json index 7fe8b9d59..cd2ce71a2 100644 --- a/plugins/importer-openapi/package-lock.json +++ b/plugins/importer-openapi/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-openapi", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, @@ -56,9 +56,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", - "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", + "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index 355c9cb3f..8df85f4ea 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json index 29c684663..b77c23c6a 100644 --- a/plugins/importer-postman/package-lock.json +++ b/plugins/importer-postman/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-postman", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.11" + "@yaakapp/api": "^0.1.12" }, "devDependencies": { "@types/node": "^20.14.9", @@ -663,9 +663,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", - "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", + "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index bf5b89cb8..3d96ed724 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -7,7 +7,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.11" + "@yaakapp/api": "^0.1.12" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json index f96ee6090..15f6d53da 100644 --- a/plugins/importer-yaak/package-lock.json +++ b/plugins/importer-yaak/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-yaak", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.11" + "@yaakapp/api": "^0.1.12" }, "devDependencies": { "@types/node": "^20.14.9", @@ -394,9 +394,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", - "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", + "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index ea6ab6cb9..aa14cafcb 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.11" + "@yaakapp/api": "^0.1.12" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/template-function-response/package-lock.json b/plugins/template-function-response/package-lock.json index 3d64a872c..d95c474f7 100644 --- a/plugins/template-function-response/package-lock.json +++ b/plugins/template-function-response/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34" }, @@ -741,9 +741,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.11.tgz", - "integrity": "sha512-dRZAXrQpftWygy9nJXiIYPzLA9om6reO/RiEacMe9RKqMjNG6FRF8cGmj7BcdyreizJOkH/DmcOpxn09kDD0XA==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", + "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/template-function-response/package.json b/plugins/template-function-response/package.json index b81478609..8d6d6567d 100644 --- a/plugins/template-function-response/package.json +++ b/plugins/template-function-response/package.json @@ -6,7 +6,7 @@ "build": "yaakcli src/index.ts" }, "dependencies": { - "@yaakapp/api": "^0.1.11", + "@yaakapp/api": "^0.1.12", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34", "@xmldom/xmldom": "^0.8.10" From d4baddc8d4aaac81b20b828904bd14e7700ca27a Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 26 Aug 2024 13:10:22 -0700 Subject: [PATCH 022/996] Fix bug --- plugins/exporter-curl/package-lock.json | 8 ++++---- plugins/exporter-curl/package.json | 2 +- plugins/filter-jsonpath/package-lock.json | 8 ++++---- plugins/filter-jsonpath/package.json | 2 +- plugins/filter-xpath/package-lock.json | 8 ++++---- plugins/filter-xpath/package.json | 2 +- plugins/importer-curl/package-lock.json | 8 ++++---- plugins/importer-curl/package.json | 2 +- plugins/importer-insomnia/package-lock.json | 8 ++++---- plugins/importer-insomnia/package.json | 2 +- plugins/importer-openapi/package-lock.json | 8 ++++---- plugins/importer-openapi/package.json | 2 +- plugins/importer-postman/package-lock.json | 8 ++++---- plugins/importer-postman/package.json | 2 +- plugins/importer-yaak/package-lock.json | 8 ++++---- plugins/importer-yaak/package.json | 2 +- plugins/template-function-response/package-lock.json | 8 ++++---- plugins/template-function-response/package.json | 2 +- plugins/template-function-response/src/index.ts | 7 ++++--- 19 files changed, 49 insertions(+), 48 deletions(-) diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json index 50e01ba04..19bbec7e5 100644 --- a/plugins/exporter-curl/package-lock.json +++ b/plugins/exporter-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "exporter-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.12" + "@yaakapp/api": "^0.1.13" }, "devDependencies": { "@types/node": "^20.14.9", @@ -701,9 +701,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", - "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", + "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index 28a892541..99185fccd 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -11,6 +11,6 @@ "vitest": "^1.4.0" }, "dependencies": { - "@yaakapp/api": "^0.1.12" + "@yaakapp/api": "^0.1.13" } } diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index 63e535b48..8b61cc569 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -8,7 +8,7 @@ "name": "filter-jsonpath", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "jsonpath-plus": "^9.0.0" }, "devDependencies": { @@ -48,9 +48,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", - "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", + "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index 4e28707c5..43c7a5b88 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "jsonpath-plus": "^9.0.0", - "@yaakapp/api": "^0.1.12" + "@yaakapp/api": "^0.1.13" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json index 6afa3055f..1a99ffc38 100644 --- a/plugins/filter-xpath/package-lock.json +++ b/plugins/filter-xpath/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "xpath": "^0.0.34" }, "devDependencies": { @@ -35,9 +35,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", - "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", + "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index 98f517ce0..fbdc198e3 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "@xmldom/xmldom": "^0.8.10", "xpath": "^0.0.34" }, diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json index 94edb0a77..d7c07fae6 100644 --- a/plugins/importer-curl/package-lock.json +++ b/plugins/importer-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "shell-quote": "^1.8.1" }, "devDependencies": { @@ -709,9 +709,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", - "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", + "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index e80877dbb..c9ba285bf 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "shell-quote": "^1.8.1" }, "devDependencies": { diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json index bbb49edab..e2513aec5 100644 --- a/plugins/importer-insomnia/package-lock.json +++ b/plugins/importer-insomnia/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-insomnia", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "yaml": "^2.4.2" }, "devDependencies": { @@ -26,9 +26,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", - "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", + "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 394a1def8..d44a0cc21 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "yaml": "^2.4.2" }, "devDependencies": { diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json index cd2ce71a2..29922f6ad 100644 --- a/plugins/importer-openapi/package-lock.json +++ b/plugins/importer-openapi/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-openapi", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, @@ -56,9 +56,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", - "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", + "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index 8df85f4ea..01e7ea27a 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json index b77c23c6a..738a3d992 100644 --- a/plugins/importer-postman/package-lock.json +++ b/plugins/importer-postman/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-postman", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.12" + "@yaakapp/api": "^0.1.13" }, "devDependencies": { "@types/node": "^20.14.9", @@ -663,9 +663,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", - "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", + "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 3d96ed724..82ccbd2f5 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -7,7 +7,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.12" + "@yaakapp/api": "^0.1.13" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json index 15f6d53da..ad581679a 100644 --- a/plugins/importer-yaak/package-lock.json +++ b/plugins/importer-yaak/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-yaak", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.12" + "@yaakapp/api": "^0.1.13" }, "devDependencies": { "@types/node": "^20.14.9", @@ -394,9 +394,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", - "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", + "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index aa14cafcb..f3d93d1e0 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -6,7 +6,7 @@ "build": "yaakcli ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.12" + "@yaakapp/api": "^0.1.13" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/template-function-response/package-lock.json b/plugins/template-function-response/package-lock.json index d95c474f7..a20869fa0 100644 --- a/plugins/template-function-response/package-lock.json +++ b/plugins/template-function-response/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34" }, @@ -741,9 +741,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.12.tgz", - "integrity": "sha512-qA+2BBZz1LGTi0wsOmlwaw6xJbE3elPIUMt/BkiRT+DqQC5spZtISsyoPXjtsM0xZc2orjoRJd0LesXH7xkD0g==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", + "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/template-function-response/package.json b/plugins/template-function-response/package.json index 8d6d6567d..f480350c5 100644 --- a/plugins/template-function-response/package.json +++ b/plugins/template-function-response/package.json @@ -6,7 +6,7 @@ "build": "yaakcli src/index.ts" }, "dependencies": { - "@yaakapp/api": "^0.1.12", + "@yaakapp/api": "^0.1.13", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34", "@xmldom/xmldom": "^0.8.10" diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts index 966e23e95..fc77f0efa 100644 --- a/plugins/template-function-response/src/index.ts +++ b/plugins/template-function-response/src/index.ts @@ -27,7 +27,6 @@ export const plugin: Plugin = { options: [ { name: 'When no responses', value: 'smart' }, { name: 'Always', value: 'always' }, - { name: 'Never', value: 'never' }, ], }, ], @@ -40,7 +39,7 @@ export const plugin: Plugin = { if (httpRequest == null) { return null; } - const renderedHttpRequest = await ctx.httpRequest.render({ httpRequest }); + const renderedHttpRequest = await ctx.httpRequest.render({ httpRequest, purpose: args.purpose }); const responses = await ctx.httpResponse.find({ requestId: httpRequest.id, limit: 1 }); @@ -52,7 +51,9 @@ export const plugin: Plugin = { // Previews happen a ton, and we don't want to send too many times on "always," so treat // it as "smart" during preview. - let behavior = args.values.behavior === 'always' && args.purpose === 'preview' ? 'smart' : args.values.behavior; + let behavior = (args.values.behavior === 'always' && args.purpose === 'preview') + ? 'smart' + : args.values.behavior; // Send if no responses and "smart," or "always" if ((behavior === 'smart' && response == null) || behavior === 'always') { From af9c5c0294792e0806573dde0241049c9788ffe8 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 26 Aug 2024 15:02:44 -0700 Subject: [PATCH 023/996] Lowercase response function name --- plugins/template-function-response/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts index fc77f0efa..c0c4f6e4b 100644 --- a/plugins/template-function-response/src/index.ts +++ b/plugins/template-function-response/src/index.ts @@ -6,7 +6,7 @@ import xpath from 'xpath'; export const plugin: Plugin = { templateFunctions: [{ - name: 'Response', + name: 'response', args: [ { type: 'http_request', From 6ce1369a883f996aa282e64c6577d3c4bda79d25 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 6 Sep 2024 06:39:57 -0700 Subject: [PATCH 024/996] Upgrade deps --- plugins/exporter-curl/package-lock.json | 8 ++++---- plugins/exporter-curl/package.json | 4 ++-- plugins/exporter-curl/tests/index.test.ts | 3 ++- plugins/filter-jsonpath/package-lock.json | 8 ++++---- plugins/filter-jsonpath/package.json | 4 ++-- plugins/filter-xpath/package-lock.json | 8 ++++---- plugins/filter-xpath/package.json | 4 ++-- plugins/importer-curl/package-lock.json | 8 ++++---- plugins/importer-curl/package.json | 4 ++-- plugins/importer-insomnia/package-lock.json | 8 ++++---- plugins/importer-insomnia/package.json | 4 ++-- plugins/importer-openapi/package-lock.json | 8 ++++---- plugins/importer-openapi/package.json | 4 ++-- plugins/importer-postman/package-lock.json | 8 ++++---- plugins/importer-postman/package.json | 4 ++-- plugins/importer-yaak/package-lock.json | 8 ++++---- plugins/importer-yaak/package.json | 4 ++-- plugins/template-function-response/package-lock.json | 8 ++++---- plugins/template-function-response/package.json | 4 ++-- 19 files changed, 56 insertions(+), 55 deletions(-) diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json index 19bbec7e5..743a9c7fe 100644 --- a/plugins/exporter-curl/package-lock.json +++ b/plugins/exporter-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "exporter-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.13" + "@yaakapp/api": "^0.1.14" }, "devDependencies": { "@types/node": "^20.14.9", @@ -701,9 +701,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", - "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", + "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index 99185fccd..efb3d2d48 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -3,7 +3,7 @@ "private": true, "version": "0.0.1", "scripts": { - "build": "yaakcli ./src/index.js" + "build": "yaakcli build ./src/index.js" }, "devDependencies": { "@types/node": "^20.14.9", @@ -11,6 +11,6 @@ "vitest": "^1.4.0" }, "dependencies": { - "@yaakapp/api": "^0.1.13" + "@yaakapp/api": "^0.1.14" } } diff --git a/plugins/exporter-curl/tests/index.test.ts b/plugins/exporter-curl/tests/index.test.ts index caceb95fb..d3d3ce36d 100644 --- a/plugins/exporter-curl/tests/index.test.ts +++ b/plugins/exporter-curl/tests/index.test.ts @@ -1,7 +1,8 @@ import { describe, expect, test } from 'vitest'; +import { Context } from '@yaakapp/api'; import { pluginHookExport } from '../src'; -const ctx = {}; +const ctx = {} as Context; describe('exporter-curl', () => { test('Exports GET with params', () => { diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index 8b61cc569..3c3a21d49 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -8,7 +8,7 @@ "name": "filter-jsonpath", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "jsonpath-plus": "^9.0.0" }, "devDependencies": { @@ -48,9 +48,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", - "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", + "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index 43c7a5b88..1e457089c 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -3,11 +3,11 @@ "private": true, "version": "0.0.1", "scripts": { - "build": "yaakcli src/index.ts" + "build": "yaakcli build ./src/index.ts" }, "dependencies": { "jsonpath-plus": "^9.0.0", - "@yaakapp/api": "^0.1.13" + "@yaakapp/api": "^0.1.14" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json index 1a99ffc38..4de261de1 100644 --- a/plugins/filter-xpath/package-lock.json +++ b/plugins/filter-xpath/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "xpath": "^0.0.34" }, "devDependencies": { @@ -35,9 +35,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", - "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", + "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index fbdc198e3..7059cd6cc 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -3,10 +3,10 @@ "private": true, "version": "0.0.1", "scripts": { - "build": "yaakcli ./src/index.js" + "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "@xmldom/xmldom": "^0.8.10", "xpath": "^0.0.34" }, diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json index d7c07fae6..624213c45 100644 --- a/plugins/importer-curl/package-lock.json +++ b/plugins/importer-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "shell-quote": "^1.8.1" }, "devDependencies": { @@ -709,9 +709,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", - "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", + "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index c9ba285bf..b48d705c0 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -3,10 +3,10 @@ "private": true, "version": "0.0.1", "scripts": { - "build": "yaakcli ./src/index.js" + "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "shell-quote": "^1.8.1" }, "devDependencies": { diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json index e2513aec5..03a718176 100644 --- a/plugins/importer-insomnia/package-lock.json +++ b/plugins/importer-insomnia/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-insomnia", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "yaml": "^2.4.2" }, "devDependencies": { @@ -26,9 +26,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", - "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", + "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index d44a0cc21..e18e82b24 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -3,10 +3,10 @@ "private": true, "version": "0.0.1", "scripts": { - "build": "yaakcli ./src/index.js" + "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "yaml": "^2.4.2" }, "devDependencies": { diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json index 29922f6ad..2a2bf26a9 100644 --- a/plugins/importer-openapi/package-lock.json +++ b/plugins/importer-openapi/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-openapi", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, @@ -56,9 +56,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", - "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", + "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index 01e7ea27a..4aec3fbd0 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -3,10 +3,10 @@ "private": true, "version": "0.0.1", "scripts": { - "build": "yaakcli ./src/index.js" + "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json index 738a3d992..cec6b28a5 100644 --- a/plugins/importer-postman/package-lock.json +++ b/plugins/importer-postman/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-postman", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.13" + "@yaakapp/api": "^0.1.14" }, "devDependencies": { "@types/node": "^20.14.9", @@ -663,9 +663,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", - "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", + "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 82ccbd2f5..37b83823a 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -4,10 +4,10 @@ "version": "0.0.1", "main": "./build/index.js", "scripts": { - "build": "yaakcli ./src/index.js" + "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.13" + "@yaakapp/api": "^0.1.14" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json index ad581679a..c0a71a07b 100644 --- a/plugins/importer-yaak/package-lock.json +++ b/plugins/importer-yaak/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-yaak", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.13" + "@yaakapp/api": "^0.1.14" }, "devDependencies": { "@types/node": "^20.14.9", @@ -394,9 +394,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", - "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", + "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index f3d93d1e0..faefca546 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -3,10 +3,10 @@ "private": true, "version": "0.0.1", "scripts": { - "build": "yaakcli ./src/index.js" + "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.13" + "@yaakapp/api": "^0.1.14" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/template-function-response/package-lock.json b/plugins/template-function-response/package-lock.json index a20869fa0..7c02fffd6 100644 --- a/plugins/template-function-response/package-lock.json +++ b/plugins/template-function-response/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34" }, @@ -741,9 +741,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.13.tgz", - "integrity": "sha512-FSYPHZV0mP967w63VXi9zYP81hPo3vjSW3/UElJLuF/8ig6WmG4p1q2oYos4Ik267Z3qSQAGN5dPMfuk3DAnBA==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", + "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", "dependencies": { "@types/node": "^22.0.0" } diff --git a/plugins/template-function-response/package.json b/plugins/template-function-response/package.json index f480350c5..70a175dc8 100644 --- a/plugins/template-function-response/package.json +++ b/plugins/template-function-response/package.json @@ -3,10 +3,10 @@ "private": true, "version": "0.0.1", "scripts": { - "build": "yaakcli src/index.ts" + "build": "yaakcli build ./src/index.ts" }, "dependencies": { - "@yaakapp/api": "^0.1.13", + "@yaakapp/api": "^0.1.14", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34", "@xmldom/xmldom": "^0.8.10" From 41c0027391bdd546704bd53cd929c8524fd5ac7a Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Sep 2024 08:53:37 -0700 Subject: [PATCH 025/996] Try something else --- .github/workflows/ci.yaml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/ci.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 000000000..7f09c2e37 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,27 @@ +name: CI +on: push + +jobs: + do-it: + strategy: + fail-fast: false + matrix: + include: + - platform: 'macos-latest' + - platform: 'ubuntu-22.04' + - platform: 'windows-latest' + runs-on: ${{ matrix.platform }} + steps: + - name: Checkout yaakapp/app + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install Yaak CLI + run: npm install -g @yaakapp/cli + + - name: Verify the Yaak CLI + run: yaakcli.exe --version From de6ed1a0cc29e57ec7e99d1076a9aca320e55a71 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Sep 2024 08:54:04 -0700 Subject: [PATCH 026/996] Undo CI job --- .github/workflows/ci.yaml | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 .github/workflows/ci.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml deleted file mode 100644 index 7f09c2e37..000000000 --- a/.github/workflows/ci.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: CI -on: push - -jobs: - do-it: - strategy: - fail-fast: false - matrix: - include: - - platform: 'macos-latest' - - platform: 'ubuntu-22.04' - - platform: 'windows-latest' - runs-on: ${{ matrix.platform }} - steps: - - name: Checkout yaakapp/app - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Install Yaak CLI - run: npm install -g @yaakapp/cli - - - name: Verify the Yaak CLI - run: yaakcli.exe --version From b72e037e6a457e67df73a21cec6197d5dbd76fc7 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Sep 2024 11:37:44 -0700 Subject: [PATCH 027/996] Remove commented code --- plugins/importer-openapi/src/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/importer-openapi/src/index.ts b/plugins/importer-openapi/src/index.ts index 782bd24bc..6ff684bf3 100644 --- a/plugins/importer-openapi/src/index.ts +++ b/plugins/importer-openapi/src/index.ts @@ -32,7 +32,5 @@ export async function pluginHookImport( return undefined; } - // console.log("HELLO", JSON.stringify(postmanCollection, null, 1)); - return pluginHookImportPostman(ctx, JSON.stringify(postmanCollection)); } From 48e62eb1d9f607a91e61d045690872a315394cd2 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Sep 2024 11:43:21 -0700 Subject: [PATCH 028/996] CI workflow --- .github/workflows/ci.yaml | 41 ++++ package.json | 3 +- plugins/exporter-curl/tests/index.test.ts | 44 ++--- plugins/importer-curl/tests/index.test.ts | 6 +- .../tests/index.test.ts | 177 ------------------ 5 files changed, 68 insertions(+), 203 deletions(-) create mode 100644 .github/workflows/ci.yaml delete mode 100644 plugins/template-function-response/tests/index.test.ts diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 000000000..fdafa3f40 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,41 @@ +name: Release + +on: push + +jobs: + ci: + runs-on: ubuntu-latest + name: CI + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "lts/*" + + - run: npm install + + - run: npm test + working-directory: npm/cli-darwin-arm64 + env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } + + - name: Publish @yaakapp/cli-darwin-x64 + run: npm publish --provenance --access public + working-directory: npm/cli-darwin-x64 + env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } + + - name: Publish @yaakapp/cli-linux-x64 + run: npm publish --provenance --access public + working-directory: npm/cli-linux-x64 + env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } + + - name: Publish @yaakapp/cli-win32-x64 + run: npm publish --provenance --access public + working-directory: npm/cli-win32-x64 + env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } + + - name: Publish @yaakapp/cli + run: npm publish --provenance --access public + working-directory: npm/cli + env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } diff --git a/package.json b/package.json index 1288ed005..8ce4ad184 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "repository": "https://github.com/yaakapp/plugins", "private": true, "scripts": { - "build": "node scripts/build-plugins.cjs" + "build": "node scripts/build-plugins.cjs", + "test": "vitest run" }, "devDependencies": { "jsonpath": "^1.1.1", diff --git a/plugins/exporter-curl/tests/index.test.ts b/plugins/exporter-curl/tests/index.test.ts index d3d3ce36d..6d334e0a3 100644 --- a/plugins/exporter-curl/tests/index.test.ts +++ b/plugins/exporter-curl/tests/index.test.ts @@ -5,9 +5,9 @@ import { pluginHookExport } from '../src'; const ctx = {} as Context; describe('exporter-curl', () => { - test('Exports GET with params', () => { + test('Exports GET with params', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { url: 'https://yaak.app', urlParameters: [ { name: 'a', value: 'aaa' }, @@ -19,9 +19,9 @@ describe('exporter-curl', () => { [`curl 'https://yaak.app'`, `--url-query 'a=aaa'`, `--url-query 'b=bbb'`].join(` \\\n `), ); }); - test('Exports POST with url form data', () => { + test('Exports POST with url form data', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { url: 'https://yaak.app', method: 'POST', bodyType: 'application/x-www-form-urlencoded', @@ -38,9 +38,9 @@ describe('exporter-curl', () => { ); }); - test('Exports PUT with multipart form', () => { + test('Exports PUT with multipart form', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { url: 'https://yaak.app', method: 'PUT', bodyType: 'multipart/form-data', @@ -63,9 +63,9 @@ describe('exporter-curl', () => { ); }); - test('Exports JSON body', () => { + test('Exports JSON body', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { url: 'https://yaak.app', method: 'POST', bodyType: 'application/json', @@ -83,9 +83,9 @@ describe('exporter-curl', () => { ); }); - test('Exports multi-line JSON body', () => { + test('Exports multi-line JSON body', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { url: 'https://yaak.app', method: 'POST', bodyType: 'application/json', @@ -103,9 +103,9 @@ describe('exporter-curl', () => { ); }); - test('Exports headers', () => { + test('Exports headers', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { headers: [ { name: 'a', value: 'aaa' }, { name: 'b', value: 'bbb', enabled: true }, @@ -115,9 +115,9 @@ describe('exporter-curl', () => { ).toEqual([`curl`, `--header 'a: aaa'`, `--header 'b: bbb'`].join(` \\\n `)); }); - test('Basic auth', () => { + test('Basic auth', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { url: 'https://yaak.app', authenticationType: 'basic', authentication: { @@ -128,9 +128,9 @@ describe('exporter-curl', () => { ).toEqual([`curl 'https://yaak.app'`, `--user 'user:pass'`].join(` \\\n `)); }); - test('Broken basic auth', () => { + test('Broken basic auth', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { url: 'https://yaak.app', authenticationType: 'basic', authentication: {}, @@ -138,9 +138,9 @@ describe('exporter-curl', () => { ).toEqual([`curl 'https://yaak.app'`, `--user ':'`].join(` \\\n `)); }); - test('Digest auth', () => { + test('Digest auth', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { url: 'https://yaak.app', authenticationType: 'digest', authentication: { @@ -151,9 +151,9 @@ describe('exporter-curl', () => { ).toEqual([`curl 'https://yaak.app'`, `--digest --user 'user:pass'`].join(` \\\n `)); }); - test('Bearer auth', () => { + test('Bearer auth', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { url: 'https://yaak.app', authenticationType: 'bearer', authentication: { @@ -163,9 +163,9 @@ describe('exporter-curl', () => { ).toEqual([`curl 'https://yaak.app'`, `--header 'Authorization: Bearer tok'`].join(` \\\n `)); }); - test('Broken bearer auth', () => { + test('Broken bearer auth', async () => { expect( - pluginHookExport(ctx, { + await pluginHookExport(ctx, { url: 'https://yaak.app', authenticationType: 'bearer', authentication: { diff --git a/plugins/importer-curl/tests/index.test.ts b/plugins/importer-curl/tests/index.test.ts index f2aac3706..b0fa10282 100644 --- a/plugins/importer-curl/tests/index.test.ts +++ b/plugins/importer-curl/tests/index.test.ts @@ -1,8 +1,8 @@ +import { Context, HttpRequest, Model, Workspace } from '@yaakapp/api'; import { describe, expect, test } from 'vitest'; -import { HttpRequest, Model, Workspace } from '../../../src-web/lib/models'; import { pluginHookImport } from '../src'; -const ctx = {}; +const ctx = {} as Context; describe('importer-curl', () => { test('Imports basic GET', () => { @@ -298,7 +298,7 @@ describe('importer-curl', () => { url: 'https://yaak.app', urlParameters: [ { name: 'foo', value: 'bar', enabled: true }, - { name: 'baz', value: 'a%20a', enabled: true }, + { name: 'baz', value: 'a a', enabled: true }, ], }), ], diff --git a/plugins/template-function-response/tests/index.test.ts b/plugins/template-function-response/tests/index.test.ts deleted file mode 100644 index caceb95fb..000000000 --- a/plugins/template-function-response/tests/index.test.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { describe, expect, test } from 'vitest'; -import { pluginHookExport } from '../src'; - -const ctx = {}; - -describe('exporter-curl', () => { - test('Exports GET with params', () => { - expect( - pluginHookExport(ctx, { - url: 'https://yaak.app', - urlParameters: [ - { name: 'a', value: 'aaa' }, - { name: 'b', value: 'bbb', enabled: true }, - { name: 'c', value: 'ccc', enabled: false }, - ], - }), - ).toEqual( - [`curl 'https://yaak.app'`, `--url-query 'a=aaa'`, `--url-query 'b=bbb'`].join(` \\\n `), - ); - }); - test('Exports POST with url form data', () => { - expect( - pluginHookExport(ctx, { - url: 'https://yaak.app', - method: 'POST', - bodyType: 'application/x-www-form-urlencoded', - body: { - form: [ - { name: 'a', value: 'aaa' }, - { name: 'b', value: 'bbb', enabled: true }, - { name: 'c', value: 'ccc', enabled: false }, - ], - }, - }), - ).toEqual( - [`curl -X POST 'https://yaak.app'`, `--data 'a=aaa'`, `--data 'b=bbb'`].join(` \\\n `), - ); - }); - - test('Exports PUT with multipart form', () => { - expect( - pluginHookExport(ctx, { - url: 'https://yaak.app', - method: 'PUT', - bodyType: 'multipart/form-data', - body: { - form: [ - { name: 'a', value: 'aaa' }, - { name: 'b', value: 'bbb', enabled: true }, - { name: 'c', value: 'ccc', enabled: false }, - { name: 'f', file: '/foo/bar.png', contentType: 'image/png' }, - ], - }, - }), - ).toEqual( - [ - `curl -X PUT 'https://yaak.app'`, - `--form 'a=aaa'`, - `--form 'b=bbb'`, - `--form f=@/foo/bar.png;type=image/png`, - ].join(` \\\n `), - ); - }); - - test('Exports JSON body', () => { - expect( - pluginHookExport(ctx, { - url: 'https://yaak.app', - method: 'POST', - bodyType: 'application/json', - body: { - text: `{"foo":"bar's"}`, - }, - headers: [{ name: 'Content-Type', value: 'application/json' }], - }), - ).toEqual( - [ - `curl -X POST 'https://yaak.app'`, - `--header 'Content-Type: application/json'`, - `--data-raw $'{"foo":"bar\\'s"}'`, - ].join(` \\\n `), - ); - }); - - test('Exports multi-line JSON body', () => { - expect( - pluginHookExport(ctx, { - url: 'https://yaak.app', - method: 'POST', - bodyType: 'application/json', - body: { - text: `{"foo":"bar",\n"baz":"qux"}`, - }, - headers: [{ name: 'Content-Type', value: 'application/json' }], - }), - ).toEqual( - [ - `curl -X POST 'https://yaak.app'`, - `--header 'Content-Type: application/json'`, - `--data-raw $'{"foo":"bar",\n"baz":"qux"}'`, - ].join(` \\\n `), - ); - }); - - test('Exports headers', () => { - expect( - pluginHookExport(ctx, { - headers: [ - { name: 'a', value: 'aaa' }, - { name: 'b', value: 'bbb', enabled: true }, - { name: 'c', value: 'ccc', enabled: false }, - ], - }), - ).toEqual([`curl`, `--header 'a: aaa'`, `--header 'b: bbb'`].join(` \\\n `)); - }); - - test('Basic auth', () => { - expect( - pluginHookExport(ctx, { - url: 'https://yaak.app', - authenticationType: 'basic', - authentication: { - username: 'user', - password: 'pass', - }, - }), - ).toEqual([`curl 'https://yaak.app'`, `--user 'user:pass'`].join(` \\\n `)); - }); - - test('Broken basic auth', () => { - expect( - pluginHookExport(ctx, { - url: 'https://yaak.app', - authenticationType: 'basic', - authentication: {}, - }), - ).toEqual([`curl 'https://yaak.app'`, `--user ':'`].join(` \\\n `)); - }); - - test('Digest auth', () => { - expect( - pluginHookExport(ctx, { - url: 'https://yaak.app', - authenticationType: 'digest', - authentication: { - username: 'user', - password: 'pass', - }, - }), - ).toEqual([`curl 'https://yaak.app'`, `--digest --user 'user:pass'`].join(` \\\n `)); - }); - - test('Bearer auth', () => { - expect( - pluginHookExport(ctx, { - url: 'https://yaak.app', - authenticationType: 'bearer', - authentication: { - token: 'tok', - }, - }), - ).toEqual([`curl 'https://yaak.app'`, `--header 'Authorization: Bearer tok'`].join(` \\\n `)); - }); - - test('Broken bearer auth', () => { - expect( - pluginHookExport(ctx, { - url: 'https://yaak.app', - authenticationType: 'bearer', - authentication: { - username: 'user', - password: 'pass', - }, - }), - ).toEqual([`curl 'https://yaak.app'`, `--header 'Authorization: Bearer '`].join(` \\\n `)); - }); -}); From 035441a492cf6d06b8e4e3454be07a1517950781 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Sep 2024 11:49:05 -0700 Subject: [PATCH 029/996] Fix tests and lint --- .github/workflows/ci.yaml | 29 ++++---------------- package-lock.json | 14 ++++++++++ package.json | 6 ++-- plugins/importer-openapi/tests/index.test.ts | 7 +++-- plugins/importer-postman/tests/index.test.ts | 18 +++--------- plugins/importer-yaak/tests/index.test.ts | 3 +- 6 files changed, 35 insertions(+), 42 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fdafa3f40..9be304b50 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -14,28 +14,11 @@ jobs: with: node-version: "lts/*" - - run: npm install + - name: Install Dependencies + run: npm install - - run: npm test - working-directory: npm/cli-darwin-arm64 - env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } + - name: Lint + run: npm run lint - - name: Publish @yaakapp/cli-darwin-x64 - run: npm publish --provenance --access public - working-directory: npm/cli-darwin-x64 - env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } - - - name: Publish @yaakapp/cli-linux-x64 - run: npm publish --provenance --access public - working-directory: npm/cli-linux-x64 - env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } - - - name: Publish @yaakapp/cli-win32-x64 - run: npm publish --provenance --access public - working-directory: npm/cli-win32-x64 - env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } - - - name: Publish @yaakapp/cli - run: npm publish --provenance --access public - working-directory: npm/cli - env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" } + - name: Run Tests + run: npm test diff --git a/package-lock.json b/package-lock.json index 1a54adcda..9ac01b9a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "name": "@yaakapp/plugins", "devDependencies": { "jsonpath": "^1.1.1", + "typescript": "^5.5.2", "vitest": "^2.0.4" } }, @@ -1408,6 +1409,19 @@ "node": ">= 0.8.0" } }, + "node_modules/typescript": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/underscore": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", diff --git a/package.json b/package.json index 8ce4ad184..d535aa6f6 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,12 @@ "private": true, "scripts": { "build": "node scripts/build-plugins.cjs", - "test": "vitest run" + "test": "vitest run", + "lint": "tsc" }, "devDependencies": { "jsonpath": "^1.1.1", - "vitest": "^2.0.4" + "vitest": "^2.0.4", + "typescript": "^5.5.2" } } diff --git a/plugins/importer-openapi/tests/index.test.ts b/plugins/importer-openapi/tests/index.test.ts index f89dcf7d4..29a2ce310 100644 --- a/plugins/importer-openapi/tests/index.test.ts +++ b/plugins/importer-openapi/tests/index.test.ts @@ -1,21 +1,24 @@ +import { Context } from '@yaakapp/api'; import * as fs from 'node:fs'; import * as path from 'node:path'; import { describe, expect, test } from 'vitest'; import { pluginHookImport } from '../src'; +const ctx = {} as Context; + describe('importer-openapi', () => { const p = path.join(__dirname, 'fixtures'); const fixtures = fs.readdirSync(p); test('Skips invalid file', async () => { - const imported = await pluginHookImport({}, '{}'); + const imported = await pluginHookImport(ctx, '{}'); expect(imported).toBeUndefined(); }) for (const fixture of fixtures) { test('Imports ' + fixture, async () => { const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); - const imported = await pluginHookImport({}, contents); + const imported = await pluginHookImport(ctx, contents); expect(imported?.resources.workspaces).toEqual([ expect.objectContaining({ name: 'Swagger Petstore - OpenAPI 3.0', diff --git a/plugins/importer-postman/tests/index.test.ts b/plugins/importer-postman/tests/index.test.ts index 108521672..0ab876734 100644 --- a/plugins/importer-postman/tests/index.test.ts +++ b/plugins/importer-postman/tests/index.test.ts @@ -1,29 +1,19 @@ +import { Context, Model } from '@yaakapp/api'; import * as fs from 'node:fs'; import * as path from 'node:path'; -import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; -import { Model } from '../../../src-web/lib/models'; +import { describe, expect, test } from 'vitest'; import { pluginHookImport } from '../src'; -let originalRandom = Math.random; +const ctx = {} as Context; describe('importer-postman', () => { - beforeEach(() => { - let i = 0; - // Psuedo-random number generator to ensure consistent ID generation - Math.random = vi.fn(() => ((i++ * 1000) % 133) / 100); - }); - - afterEach(() => { - Math.random = originalRandom; - }); - const p = path.join(__dirname, 'fixtures'); const fixtures = fs.readdirSync(p); for (const fixture of fixtures) { test('Imports ' + fixture, () => { const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); - const imported = pluginHookImport({}, contents); + const imported = pluginHookImport(ctx, contents); const folder0 = newId('folder'); const folder1 = newId('folder'); expect(imported).toEqual({ diff --git a/plugins/importer-yaak/tests/index.test.ts b/plugins/importer-yaak/tests/index.test.ts index 38e44133a..0e4187d27 100644 --- a/plugins/importer-yaak/tests/index.test.ts +++ b/plugins/importer-yaak/tests/index.test.ts @@ -1,7 +1,8 @@ +import { Context } from '@yaakapp/api'; import { describe, expect, test } from 'vitest'; import { pluginHookImport } from '../src'; -const ctx = {}; +const ctx = {} as Context; describe('importer-yaak', () => { test('Skips invalid imports', () => { From 63f391ea5f64f9b83030e8cc4c1cdd37a8554900 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Sep 2024 12:08:33 -0700 Subject: [PATCH 030/996] Build plugins in workflow --- .github/workflows/ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9be304b50..bd320cde1 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,6 +17,9 @@ jobs: - name: Install Dependencies run: npm install + - name: Build Plugins + run: npm run build + - name: Lint run: npm run lint From 107fe46852b6ebb92778b5a064463ed2a8eec886 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Sep 2024 12:11:37 -0700 Subject: [PATCH 031/996] Add @yaakapp/cli dependency --- plugins/exporter-curl/package-lock.json | 57 +++++++++++++++++++ plugins/exporter-curl/package.json | 9 +-- plugins/filter-jsonpath/package-lock.json | 57 +++++++++++++++++++ plugins/filter-jsonpath/package.json | 1 + plugins/filter-xpath/package-lock.json | 57 +++++++++++++++++++ plugins/filter-xpath/package.json | 1 + plugins/importer-curl/package-lock.json | 57 +++++++++++++++++++ plugins/importer-curl/package.json | 1 + plugins/importer-insomnia/package-lock.json | 57 +++++++++++++++++++ plugins/importer-insomnia/package.json | 1 + plugins/importer-postman/package-lock.json | 57 +++++++++++++++++++ plugins/importer-postman/package.json | 1 + plugins/importer-yaak/package-lock.json | 57 +++++++++++++++++++ plugins/importer-yaak/package.json | 1 + .../package-lock.json | 52 +++++++++++++++++ .../template-function-response/package.json | 1 + 16 files changed, 463 insertions(+), 4 deletions(-) diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json index 743a9c7fe..169e246d2 100644 --- a/plugins/exporter-curl/package-lock.json +++ b/plugins/exporter-curl/package-lock.json @@ -12,6 +12,7 @@ }, "devDependencies": { "@types/node": "^20.14.9", + "@yaakapp/cli": "^0.0.42", "typescript": "^5.5.2", "vitest": "^1.4.0" } @@ -721,6 +722,62 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" }, + "node_modules/@yaakapp/cli": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", + "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "yaakcli": "bin/cli.js" + }, + "optionalDependencies": { + "@yaakapp/cli-darwin-arm64": "0.0.42", + "@yaakapp/cli-darwin-x64": "0.0.42", + "@yaakapp/cli-linux-x64": "0.0.42", + "@yaakapp/cli-win32-x64": "0.0.42" + } + }, + "node_modules/@yaakapp/cli-darwin-arm64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", + "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-darwin-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", + "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-linux-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", + "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-win32-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", + "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index efb3d2d48..1ee36f063 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -5,12 +5,13 @@ "scripts": { "build": "yaakcli build ./src/index.js" }, + "dependencies": { + "@yaakapp/api": "^0.1.14" + }, "devDependencies": { "@types/node": "^20.14.9", "typescript": "^5.5.2", - "vitest": "^1.4.0" - }, - "dependencies": { - "@yaakapp/api": "^0.1.14" + "vitest": "^1.4.0", + "@yaakapp/cli": "^0.0.42" } } diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index 3c3a21d49..6b8796bbd 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -13,6 +13,7 @@ }, "devDependencies": { "@types/node": "^20.14.9", + "@yaakapp/cli": "^0.0.42", "typescript": "^5.5.2" } }, @@ -68,6 +69,62 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, + "node_modules/@yaakapp/cli": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", + "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "yaakcli": "bin/cli.js" + }, + "optionalDependencies": { + "@yaakapp/cli-darwin-arm64": "0.0.42", + "@yaakapp/cli-darwin-x64": "0.0.42", + "@yaakapp/cli-linux-x64": "0.0.42", + "@yaakapp/cli-win32-x64": "0.0.42" + } + }, + "node_modules/@yaakapp/cli-darwin-arm64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", + "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-darwin-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", + "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-linux-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", + "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-win32-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", + "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/jsep": { "version": "1.3.9", "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.9.tgz", diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index 1e457089c..578507ecd 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -10,6 +10,7 @@ "@yaakapp/api": "^0.1.14" }, "devDependencies": { + "@yaakapp/cli": "^0.0.42", "@types/node": "^20.14.9", "typescript": "^5.5.2" } diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json index 4de261de1..f5d9f0915 100644 --- a/plugins/filter-xpath/package-lock.json +++ b/plugins/filter-xpath/package-lock.json @@ -14,6 +14,7 @@ }, "devDependencies": { "@types/node": "^20.14.9", + "@yaakapp/cli": "^0.0.42", "typescript": "^5.5.2" } }, @@ -55,6 +56,62 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, + "node_modules/@yaakapp/cli": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", + "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "yaakcli": "bin/cli.js" + }, + "optionalDependencies": { + "@yaakapp/cli-darwin-arm64": "0.0.42", + "@yaakapp/cli-darwin-x64": "0.0.42", + "@yaakapp/cli-linux-x64": "0.0.42", + "@yaakapp/cli-win32-x64": "0.0.42" + } + }, + "node_modules/@yaakapp/cli-darwin-arm64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", + "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-darwin-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", + "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-linux-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", + "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-win32-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", + "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/typescript": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index 7059cd6cc..67e5230a0 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -11,6 +11,7 @@ "xpath": "^0.0.34" }, "devDependencies": { + "@yaakapp/cli": "^0.0.42", "@types/node": "^20.14.9", "typescript": "^5.5.2" } diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json index 624213c45..8b711cb68 100644 --- a/plugins/importer-curl/package-lock.json +++ b/plugins/importer-curl/package-lock.json @@ -14,6 +14,7 @@ "devDependencies": { "@types/node": "^20.14.9", "@types/shell-quote": "^1.7.5", + "@yaakapp/cli": "^0.0.42", "typescript": "^5.5.2", "vitest": "^1.4.0" } @@ -729,6 +730,62 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, + "node_modules/@yaakapp/cli": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", + "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "yaakcli": "bin/cli.js" + }, + "optionalDependencies": { + "@yaakapp/cli-darwin-arm64": "0.0.42", + "@yaakapp/cli-darwin-x64": "0.0.42", + "@yaakapp/cli-linux-x64": "0.0.42", + "@yaakapp/cli-win32-x64": "0.0.42" + } + }, + "node_modules/@yaakapp/cli-darwin-arm64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", + "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-darwin-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", + "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-linux-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", + "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-win32-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", + "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index b48d705c0..c6fed24df 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -10,6 +10,7 @@ "shell-quote": "^1.8.1" }, "devDependencies": { + "@yaakapp/cli": "^0.0.42", "@types/node": "^20.14.9", "@types/shell-quote": "^1.7.5", "typescript": "^5.5.2", diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json index 03a718176..d483dbcda 100644 --- a/plugins/importer-insomnia/package-lock.json +++ b/plugins/importer-insomnia/package-lock.json @@ -13,6 +13,7 @@ }, "devDependencies": { "@types/node": "^20.14.9", + "@yaakapp/cli": "^0.0.42", "typescript": "^5.5.2" } }, @@ -46,6 +47,62 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, + "node_modules/@yaakapp/cli": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", + "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "yaakcli": "bin/cli.js" + }, + "optionalDependencies": { + "@yaakapp/cli-darwin-arm64": "0.0.42", + "@yaakapp/cli-darwin-x64": "0.0.42", + "@yaakapp/cli-linux-x64": "0.0.42", + "@yaakapp/cli-win32-x64": "0.0.42" + } + }, + "node_modules/@yaakapp/cli-darwin-arm64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", + "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-darwin-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", + "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-linux-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", + "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-win32-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", + "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/typescript": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index e18e82b24..6b4036596 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -10,6 +10,7 @@ "yaml": "^2.4.2" }, "devDependencies": { + "@yaakapp/cli": "^0.0.42", "@types/node": "^20.14.9", "typescript": "^5.5.2" } diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json index cec6b28a5..5ec3241aa 100644 --- a/plugins/importer-postman/package-lock.json +++ b/plugins/importer-postman/package-lock.json @@ -12,6 +12,7 @@ }, "devDependencies": { "@types/node": "^20.14.9", + "@yaakapp/cli": "^0.0.42", "esbuild": "^0.21.5", "typescript": "^5.5.2", "vitest": "^1.4.0" @@ -683,6 +684,62 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, + "node_modules/@yaakapp/cli": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", + "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "yaakcli": "bin/cli.js" + }, + "optionalDependencies": { + "@yaakapp/cli-darwin-arm64": "0.0.42", + "@yaakapp/cli-darwin-x64": "0.0.42", + "@yaakapp/cli-linux-x64": "0.0.42", + "@yaakapp/cli-win32-x64": "0.0.42" + } + }, + "node_modules/@yaakapp/cli-darwin-arm64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", + "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-darwin-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", + "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-linux-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", + "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-win32-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", + "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 37b83823a..41ef569d1 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -10,6 +10,7 @@ "@yaakapp/api": "^0.1.14" }, "devDependencies": { + "@yaakapp/cli": "^0.0.42", "@types/node": "^20.14.9", "esbuild": "^0.21.5", "typescript": "^5.5.2", diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json index c0a71a07b..43241e860 100644 --- a/plugins/importer-yaak/package-lock.json +++ b/plugins/importer-yaak/package-lock.json @@ -12,6 +12,7 @@ }, "devDependencies": { "@types/node": "^20.14.9", + "@yaakapp/cli": "^0.0.42", "esbuild": "^0.21.5", "typescript": "^5.5.2" } @@ -414,6 +415,62 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, + "node_modules/@yaakapp/cli": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", + "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "yaakcli": "bin/cli.js" + }, + "optionalDependencies": { + "@yaakapp/cli-darwin-arm64": "0.0.42", + "@yaakapp/cli-darwin-x64": "0.0.42", + "@yaakapp/cli-linux-x64": "0.0.42", + "@yaakapp/cli-win32-x64": "0.0.42" + } + }, + "node_modules/@yaakapp/cli-darwin-arm64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", + "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-darwin-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", + "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-linux-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", + "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-win32-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", + "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index faefca546..db9e64f4d 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -9,6 +9,7 @@ "@yaakapp/api": "^0.1.14" }, "devDependencies": { + "@yaakapp/cli": "^0.0.42", "@types/node": "^20.14.9", "esbuild": "^0.21.5", "typescript": "^5.5.2" diff --git a/plugins/template-function-response/package-lock.json b/plugins/template-function-response/package-lock.json index 7c02fffd6..a72e2c383 100644 --- a/plugins/template-function-response/package-lock.json +++ b/plugins/template-function-response/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@xmldom/xmldom": "^0.8.10", "@yaakapp/api": "^0.1.14", + "@yaakapp/cli": "^0.0.42", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34" }, @@ -761,6 +762,57 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" }, + "node_modules/@yaakapp/cli": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", + "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", + "hasInstallScript": true, + "bin": { + "yaakcli": "bin/cli.js" + }, + "optionalDependencies": { + "@yaakapp/cli-darwin-arm64": "0.0.42", + "@yaakapp/cli-darwin-x64": "0.0.42", + "@yaakapp/cli-linux-x64": "0.0.42", + "@yaakapp/cli-win32-x64": "0.0.42" + } + }, + "node_modules/@yaakapp/cli-darwin-arm64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", + "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-darwin-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", + "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-linux-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", + "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-win32-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", + "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", diff --git a/plugins/template-function-response/package.json b/plugins/template-function-response/package.json index 70a175dc8..cfad12360 100644 --- a/plugins/template-function-response/package.json +++ b/plugins/template-function-response/package.json @@ -12,6 +12,7 @@ "@xmldom/xmldom": "^0.8.10" }, "devDependencies": { + "@yaakapp/cli": "^0.0.42", "@types/jsonpath": "^0.2.4", "@types/node": "^20.14.9", "typescript": "^5.5.2", From 9ae932823f1ce804b5f2ea5d66963e27f8c06c9e Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Sep 2024 12:13:52 -0700 Subject: [PATCH 032/996] Oops, missed one --- plugins/importer-openapi/package-lock.json | 57 ++++++++++++++++++++++ plugins/importer-openapi/package.json | 1 + 2 files changed, 58 insertions(+) diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json index 2a2bf26a9..2bd77758c 100644 --- a/plugins/importer-openapi/package-lock.json +++ b/plugins/importer-openapi/package-lock.json @@ -15,6 +15,7 @@ "devDependencies": { "@types/node": "^20.14.9", "@types/openapi-to-postmanv2": "^3.2.4", + "@yaakapp/cli": "^0.0.42", "typescript": "^5.5.2" } }, @@ -76,6 +77,62 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, + "node_modules/@yaakapp/cli": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", + "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "yaakcli": "bin/cli.js" + }, + "optionalDependencies": { + "@yaakapp/cli-darwin-arm64": "0.0.42", + "@yaakapp/cli-darwin-x64": "0.0.42", + "@yaakapp/cli-linux-x64": "0.0.42", + "@yaakapp/cli-win32-x64": "0.0.42" + } + }, + "node_modules/@yaakapp/cli-darwin-arm64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", + "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-darwin-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", + "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-linux-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", + "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-win32-x64": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", + "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/ajv": { "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index 4aec3fbd0..3a6fc5241 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -11,6 +11,7 @@ "yaml": "^2.4.2" }, "devDependencies": { + "@yaakapp/cli": "^0.0.42", "@types/node": "^20.14.9", "@types/openapi-to-postmanv2": "^3.2.4", "typescript": "^5.5.2" From 75df5f8094c758567395ac6cf752cd8feb33d2a6 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Sep 2024 12:17:24 -0700 Subject: [PATCH 033/996] setup-node v4 --- .github/workflows/ci.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bd320cde1..6c11c26c0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,9 +10,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: "lts/*" + uses: actions/setup-node@v4 - name: Install Dependencies run: npm install From 29d2d0ec620e8ab9d5a7bfb10e0200c7b2de1344 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 16 Sep 2024 06:37:48 -0700 Subject: [PATCH 034/996] Prevent infinite recursion in response tag Closes yaakapp/app#90 --- plugins/template-function-response/src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts index c0c4f6e4b..023707f1e 100644 --- a/plugins/template-function-response/src/index.ts +++ b/plugins/template-function-response/src/index.ts @@ -39,7 +39,6 @@ export const plugin: Plugin = { if (httpRequest == null) { return null; } - const renderedHttpRequest = await ctx.httpRequest.render({ httpRequest, purpose: args.purpose }); const responses = await ctx.httpResponse.find({ requestId: httpRequest.id, limit: 1 }); @@ -57,6 +56,8 @@ export const plugin: Plugin = { // Send if no responses and "smart," or "always" if ((behavior === 'smart' && response == null) || behavior === 'always') { + // NOTE: Render inside this conditional, or we'll get infinite recursion (render->render->...) + const renderedHttpRequest = await ctx.httpRequest.render({ httpRequest, purpose: args.purpose }); response = await ctx.httpRequest.send({ httpRequest: renderedHttpRequest }); } From 92ac91733ea2aa647504db70dee42d7495d870cc Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 17 Sep 2024 05:58:21 -0700 Subject: [PATCH 035/996] Handle Postman URL query and variable fields --- plugins/importer-postman/src/index.ts | 46 ++++-- .../{nested.json => nested.input.json} | 0 .../tests/fixtures/nested.output.json | 77 ++++++++++ .../tests/fixtures/params.input.json | 136 ++++++++++++++++++ .../tests/fixtures/params.output.json | 90 ++++++++++++ plugins/importer-postman/tests/index.test.ts | 73 ++-------- .../package-lock.json | 7 +- 7 files changed, 356 insertions(+), 73 deletions(-) rename plugins/importer-postman/tests/fixtures/{nested.json => nested.input.json} (100%) create mode 100644 plugins/importer-postman/tests/fixtures/nested.output.json create mode 100644 plugins/importer-postman/tests/fixtures/params.input.json create mode 100644 plugins/importer-postman/tests/fixtures/params.output.json diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts index 3ab59a55c..229901d04 100644 --- a/plugins/importer-postman/src/index.ts +++ b/plugins/importer-postman/src/index.ts @@ -1,4 +1,13 @@ -import { Environment, Folder, HttpRequest, HttpRequestHeader, Model, Workspace, Context } from '@yaakapp/api'; +import { + Environment, + Folder, + HttpRequest, + HttpRequestHeader, + Model, + Workspace, + Context, + HttpUrlParameter, +} from '@yaakapp/api'; const POSTMAN_2_1_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'; const POSTMAN_2_0_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json'; @@ -84,6 +93,8 @@ export function pluginHookImport( headers.push(bodyPatchHeader); } + const { url, urlParameters } = convertUrl(r.url); + const request: ExportResources['httpRequests'][0] = { model: 'http_request', id: generateId('http_request'), @@ -91,7 +102,8 @@ export function pluginHookImport( folderId, name: v.name, method: r.method || 'GET', - url: typeof r.url === 'string' ? r.url : convertUrl(toRecord(r.url)), + url, + urlParameters, body: bodyPatch.body, bodyType: bodyPatch.bodyType, authentication: authPatch.authentication, @@ -111,11 +123,13 @@ export function pluginHookImport( return { resources: convertTemplateSyntax(exportResources) }; } -function convertUrl(url: Record) { - if ('raw' in url) { - return url.raw; +function convertUrl(url: string | any): Pick { + if (typeof url === 'string') { + return { url, urlParameters: [] }; } + url = toRecord(url); + let v = ''; if ('protocol' in url && typeof url.protocol === 'string') { @@ -134,9 +148,25 @@ function convertUrl(url: Record) { v += `/${Array.isArray(url.path) ? url.path.join('/') : url.path}`; } + const params: HttpUrlParameter[] = []; if ('query' in url && Array.isArray(url.query) && url.query.length > 0) { - const qs = url.query.map(q => `${q.key ?? ''}=${q.value ?? ''}`).join('&'); - v += `?${qs}`; + for (const query of url.query) { + params.push({ + name: query.key ?? '', + value: query.value ?? '', + enabled: !query.disabled, + }); + } + } + + if ('variable' in url && Array.isArray(url.variable) && url.variable.length > 0) { + for (const v of url.variable) { + params.push({ + name: ':' + (v.key ?? ''), + value: v.value ?? '', + enabled: !v.disabled, + }); + } } if ('hash' in url && typeof url.hash === 'string') { @@ -145,7 +175,7 @@ function convertUrl(url: Record) { // TODO: Implement url.variables (path variables) - return v; + return { url: v, urlParameters: params }; } function importAuth( diff --git a/plugins/importer-postman/tests/fixtures/nested.json b/plugins/importer-postman/tests/fixtures/nested.input.json similarity index 100% rename from plugins/importer-postman/tests/fixtures/nested.json rename to plugins/importer-postman/tests/fixtures/nested.input.json diff --git a/plugins/importer-postman/tests/fixtures/nested.output.json b/plugins/importer-postman/tests/fixtures/nested.output.json new file mode 100644 index 000000000..9b7cc2c53 --- /dev/null +++ b/plugins/importer-postman/tests/fixtures/nested.output.json @@ -0,0 +1,77 @@ +{ + "resources": { + "workspaces": [ + { + "model": "workspace", + "id": "GENERATE_ID::WORKSPACE_0", + "name": "New Collection", + "description": "", + "variables": [] + } + ], + "environments": [], + "httpRequests": [ + { + "model": "http_request", + "id": "GENERATE_ID::HTTP_REQUEST_0", + "workspaceId": "GENERATE_ID::WORKSPACE_0", + "folderId": "GENERATE_ID::FOLDER_1", + "name": "Request 1", + "method": "GET", + "url": "", + "urlParameters": [], + "body": {}, + "bodyType": null, + "authentication": {}, + "authenticationType": null, + "headers": [] + }, + { + "model": "http_request", + "id": "GENERATE_ID::HTTP_REQUEST_1", + "workspaceId": "GENERATE_ID::WORKSPACE_0", + "folderId": "GENERATE_ID::FOLDER_0", + "name": "Request 2", + "method": "GET", + "url": "", + "urlParameters": [], + "body": {}, + "bodyType": null, + "authentication": {}, + "authenticationType": null, + "headers": [] + }, + { + "model": "http_request", + "id": "GENERATE_ID::HTTP_REQUEST_2", + "workspaceId": "GENERATE_ID::WORKSPACE_0", + "folderId": null, + "name": "Request 3", + "method": "GET", + "url": "", + "urlParameters": [], + "body": {}, + "bodyType": null, + "authentication": {}, + "authenticationType": null, + "headers": [] + } + ], + "folders": [ + { + "model": "folder", + "workspaceId": "GENERATE_ID::WORKSPACE_0", + "id": "GENERATE_ID::FOLDER_0", + "name": "Top Folder", + "folderId": null + }, + { + "model": "folder", + "workspaceId": "GENERATE_ID::WORKSPACE_0", + "id": "GENERATE_ID::FOLDER_1", + "name": "Nested Folder", + "folderId": "GENERATE_ID::FOLDER_0" + } + ] + } +} diff --git a/plugins/importer-postman/tests/fixtures/params.input.json b/plugins/importer-postman/tests/fixtures/params.input.json new file mode 100644 index 000000000..f2969d245 --- /dev/null +++ b/plugins/importer-postman/tests/fixtures/params.input.json @@ -0,0 +1,136 @@ +{ + "info": { + "_postman_id": "9e6dfada-256c-49ea-a38f-7d1b05b7ca2d", + "name": "New Collection", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "18798" + }, + "item": [ + { + "name": "Form URL", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "baeare", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "X-foo", + "value": "bar", + "description": "description" + }, + { + "key": "Disabled", + "value": "tnroant", + "description": "ntisorantosra", + "disabled": true + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "Key", + "contentType": "Custom/COntent", + "description": "DEscription", + "type": "file", + "src": "/Users/gschier/Desktop/Screenshot 2024-05-31 at 12.05.11 PM.png" + } + ] + }, + "url": { + "raw": "example.com/:foo/:bar?q=qqq&", + "host": [ + "example", + "com" + ], + "path": [ + ":foo", + ":bar" + ], + "query": [ + { + "key": "disabled", + "value": "secondvalue", + "description": "this is disabled", + "disabled": true + }, + { + "key": "q", + "value": "qqq", + "description": "hello" + }, + { + "key": "", + "value": null + } + ], + "variable": [ + { + "key": "foo", + "value": "fff", + "description": "Description" + }, + { + "key": "bar", + "value": "bbb", + "description": "bbb description" + } + ] + } + }, + "response": [] + } + ], + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "globalpass", + "type": "string" + }, + { + "key": "username", + "value": "globaluser", + "type": "string" + } + ] + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "key": "COLLECTION VARIABLE", + "value": "collection variable", + "type": "string" + } + ] +} diff --git a/plugins/importer-postman/tests/fixtures/params.output.json b/plugins/importer-postman/tests/fixtures/params.output.json new file mode 100644 index 000000000..2ad692aeb --- /dev/null +++ b/plugins/importer-postman/tests/fixtures/params.output.json @@ -0,0 +1,90 @@ +{ + "resources": { + "workspaces": [ + { + "model": "workspace", + "id": "GENERATE_ID::WORKSPACE_1", + "name": "New Collection", + "description": "", + "variables": [ + { + "name": "COLLECTION VARIABLE", + "value": "collection variable" + } + ] + } + ], + "environments": [], + "httpRequests": [ + { + "model": "http_request", + "id": "GENERATE_ID::HTTP_REQUEST_3", + "workspaceId": "GENERATE_ID::WORKSPACE_1", + "folderId": null, + "name": "Form URL", + "method": "POST", + "url": "example.com/:foo/:bar", + "urlParameters": [ + { + "name": "disabled", + "value": "secondvalue", + "enabled": false + }, + { + "name": "q", + "value": "qqq", + "enabled": true + }, + { + "name": "", + "value": "", + "enabled": true + }, + { + "name": ":foo", + "value": "fff", + "enabled": true + }, + { + "name": ":bar", + "value": "bbb", + "enabled": true + } + ], + "body": { + "form": [ + { + "enabled": true, + "contentType": "Custom/COntent", + "name": "Key", + "file": "/Users/gschier/Desktop/Screenshot 2024-05-31 at 12.05.11 PM.png" + } + ] + }, + "bodyType": "multipart/form-data", + "authentication": { + "token": "" + }, + "authenticationType": "bearer", + "headers": [ + { + "name": "X-foo", + "value": "bar", + "enabled": true + }, + { + "name": "Disabled", + "value": "tnroant", + "enabled": false + }, + { + "name": "Content-Type", + "value": "multipart/form-data", + "enabled": true + } + ] + } + ], + "folders": [] + } +} diff --git a/plugins/importer-postman/tests/index.test.ts b/plugins/importer-postman/tests/index.test.ts index 0ab876734..350662696 100644 --- a/plugins/importer-postman/tests/index.test.ts +++ b/plugins/importer-postman/tests/index.test.ts @@ -1,4 +1,4 @@ -import { Context, Model } from '@yaakapp/api'; +import { Context } from '@yaakapp/api'; import * as fs from 'node:fs'; import * as path from 'node:path'; import { describe, expect, test } from 'vitest'; @@ -11,71 +11,16 @@ describe('importer-postman', () => { const fixtures = fs.readdirSync(p); for (const fixture of fixtures) { + if (fixture.includes('.output')) { + continue; + } + test('Imports ' + fixture, () => { const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); - const imported = pluginHookImport(ctx, contents); - const folder0 = newId('folder'); - const folder1 = newId('folder'); - expect(imported).toEqual({ - resources: expect.objectContaining({ - workspaces: [ - expect.objectContaining({ - id: newId('workspace'), - model: 'workspace', - name: 'New Collection', - }), - ], - folders: expect.arrayContaining([ - expect.objectContaining({ - id: folder0, - model: 'folder', - workspaceId: existingId('workspace'), - name: 'Top Folder', - }), - expect.objectContaining({ - folderId: folder0, - id: folder1, - model: 'folder', - workspaceId: existingId('workspace'), - name: 'Nested Folder', - }), - ]), - httpRequests: expect.arrayContaining([ - expect.objectContaining({ - id: newId('http_request'), - model: 'http_request', - name: 'Request 1', - workspaceId: existingId('workspace'), - folderId: folder1, - }), - expect.objectContaining({ - id: newId('http_request'), - model: 'http_request', - name: 'Request 2', - workspaceId: existingId('workspace'), - folderId: folder0, - }), - expect.objectContaining({ - id: newId('http_request'), - model: 'http_request', - name: 'Request 3', - workspaceId: existingId('workspace'), - folderId: null, - }), - ]), - }), - }); + const expected = fs.readFileSync(path.join(p, fixture.replace('.input', '.output')), 'utf-8'); + const result = pluginHookImport(ctx, contents); + // console.log(JSON.stringify(result, null, 2)) + expect(result).toEqual(JSON.parse(expected)); }); } }); - -const idCount: Partial> = {}; - -function newId(model: Model['model']): string { - idCount[model] = (idCount[model] ?? -1) + 1; - return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`; -} - -function existingId(model: Model['model']): string { - return `GENERATE_ID::${model.toUpperCase()}_${idCount[model] ?? 0}`; -} diff --git a/plugins/template-function-response/package-lock.json b/plugins/template-function-response/package-lock.json index a72e2c383..b0871814b 100644 --- a/plugins/template-function-response/package-lock.json +++ b/plugins/template-function-response/package-lock.json @@ -10,13 +10,13 @@ "dependencies": { "@xmldom/xmldom": "^0.8.10", "@yaakapp/api": "^0.1.14", - "@yaakapp/cli": "^0.0.42", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34" }, "devDependencies": { "@types/jsonpath": "^0.2.4", "@types/node": "^20.14.9", + "@yaakapp/cli": "^0.0.42", "typescript": "^5.5.2", "vitest": "^1.4.0" } @@ -766,6 +766,7 @@ "version": "0.0.42", "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", + "dev": true, "hasInstallScript": true, "bin": { "yaakcli": "bin/cli.js" @@ -781,6 +782,7 @@ "version": "0.0.42", "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", + "dev": true, "optional": true, "os": [ "darwin" @@ -790,6 +792,7 @@ "version": "0.0.42", "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", + "dev": true, "optional": true, "os": [ "darwin" @@ -799,6 +802,7 @@ "version": "0.0.42", "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", + "dev": true, "optional": true, "os": [ "linux" @@ -808,6 +812,7 @@ "version": "0.0.42", "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", + "dev": true, "optional": true, "os": [ "win32" From 31dbb1544811b2be62425d769eca3caccc992f9d Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 19 Sep 2024 14:01:29 -0700 Subject: [PATCH 036/996] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d90dd263c..276dc8a77 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # Yaak Plugins -To-do +This repository contains all the Yaak plugins that are bundled within the application (can't be uninstalled). From aed73482d1cccbd4e4a8d04b57dfcf3b954ec2d1 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 20 Sep 2024 07:09:01 -0700 Subject: [PATCH 037/996] Bump @yaakapp/api deps --- plugins/exporter-curl/package-lock.json | 26 ++++++++++--------- plugins/exporter-curl/package.json | 2 +- plugins/exporter-curl/src/index.ts | 6 ++--- plugins/filter-jsonpath/package-lock.json | 26 ++++++++++--------- plugins/filter-jsonpath/package.json | 2 +- plugins/filter-xpath/package-lock.json | 26 ++++++++++--------- plugins/filter-xpath/package.json | 2 +- plugins/importer-curl/package-lock.json | 26 ++++++++++--------- plugins/importer-curl/package.json | 2 +- plugins/importer-insomnia/package-lock.json | 26 ++++++++++--------- plugins/importer-insomnia/package.json | 2 +- plugins/importer-openapi/package-lock.json | 26 ++++++++++--------- plugins/importer-openapi/package.json | 2 +- plugins/importer-postman/package-lock.json | 26 ++++++++++--------- plugins/importer-postman/package.json | 2 +- plugins/importer-yaak/package-lock.json | 26 ++++++++++--------- plugins/importer-yaak/package.json | 2 +- .../package-lock.json | 26 ++++++++++--------- .../template-function-response/package.json | 2 +- .../template-function-response/src/index.ts | 4 +-- 20 files changed, 140 insertions(+), 122 deletions(-) diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json index 169e246d2..6da045bfc 100644 --- a/plugins/exporter-curl/package-lock.json +++ b/plugins/exporter-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "exporter-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.14" + "@yaakapp/api": "^0.2.5" }, "devDependencies": { "@types/node": "^20.14.9", @@ -702,25 +702,27 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", - "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", + "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", "dependencies": { - "@types/node": "^22.0.0" + "@types/node": "^22.5.4" } }, "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz", - "integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "license": "MIT", "dependencies": { - "undici-types": "~6.13.0" + "undici-types": "~6.19.2" } }, "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/@yaakapp/cli": { "version": "0.0.42", diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index 1ee36f063..7dbbe30b6 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.14" + "@yaakapp/api": "^0.2.5" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts index a87da82e7..2bf3b7afe 100644 --- a/plugins/exporter-curl/src/index.ts +++ b/plugins/exporter-curl/src/index.ts @@ -1,8 +1,8 @@ -import { Context, HttpRequest, Plugin } from '@yaakapp/api'; +import { Context, HttpRequest, PluginDefinition } from '@yaakapp/api'; const NEWLINE = '\\\n '; -export const plugin: Plugin = { +export const plugin: PluginDefinition = { httpRequestActions: [{ key: 'export-curl', label: 'Copy as Curl', @@ -11,7 +11,7 @@ export const plugin: Plugin = { const rendered_request = await ctx.httpRequest.render({ httpRequest: args.httpRequest, purpose: 'preview' }); const data = await pluginHookExport(ctx, rendered_request); ctx.clipboard.copyText(data); - ctx.toast.show({ variant: 'copied', message: 'Curl copied to clipboard' }); + ctx.toast.show({ message: 'Curl copied to clipboard', icon: 'copy' }); }, }], }; diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index 6b8796bbd..36b80dc2a 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -8,7 +8,7 @@ "name": "filter-jsonpath", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "jsonpath-plus": "^9.0.0" }, "devDependencies": { @@ -49,25 +49,27 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", - "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", + "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", "dependencies": { - "@types/node": "^22.0.0" + "@types/node": "^22.5.4" } }, "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "license": "MIT", "dependencies": { - "undici-types": "~6.18.2" + "undici-types": "~6.19.2" } }, "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/@yaakapp/cli": { "version": "0.0.42", diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index 578507ecd..4485f0716 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "jsonpath-plus": "^9.0.0", - "@yaakapp/api": "^0.1.14" + "@yaakapp/api": "^0.2.5" }, "devDependencies": { "@yaakapp/cli": "^0.0.42", diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json index f5d9f0915..4e27df34b 100644 --- a/plugins/filter-xpath/package-lock.json +++ b/plugins/filter-xpath/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "xpath": "^0.0.34" }, "devDependencies": { @@ -36,25 +36,27 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", - "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", + "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", "dependencies": { - "@types/node": "^22.0.0" + "@types/node": "^22.5.4" } }, "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "license": "MIT", "dependencies": { - "undici-types": "~6.18.2" + "undici-types": "~6.19.2" } }, "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/@yaakapp/cli": { "version": "0.0.42", diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index 67e5230a0..7018698cf 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "@xmldom/xmldom": "^0.8.10", "xpath": "^0.0.34" }, diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json index 8b711cb68..686d0c673 100644 --- a/plugins/importer-curl/package-lock.json +++ b/plugins/importer-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "shell-quote": "^1.8.1" }, "devDependencies": { @@ -710,25 +710,27 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", - "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", + "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", "dependencies": { - "@types/node": "^22.0.0" + "@types/node": "^22.5.4" } }, "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "license": "MIT", "dependencies": { - "undici-types": "~6.18.2" + "undici-types": "~6.19.2" } }, "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/@yaakapp/cli": { "version": "0.0.42", diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index c6fed24df..41fcc851e 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "shell-quote": "^1.8.1" }, "devDependencies": { diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json index d483dbcda..a1c7febd4 100644 --- a/plugins/importer-insomnia/package-lock.json +++ b/plugins/importer-insomnia/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-insomnia", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "yaml": "^2.4.2" }, "devDependencies": { @@ -27,25 +27,27 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", - "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", + "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", "dependencies": { - "@types/node": "^22.0.0" + "@types/node": "^22.5.4" } }, "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "license": "MIT", "dependencies": { - "undici-types": "~6.18.2" + "undici-types": "~6.19.2" } }, "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/@yaakapp/cli": { "version": "0.0.42", diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 6b4036596..1bc2ad034 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "yaml": "^2.4.2" }, "devDependencies": { diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json index 2bd77758c..013c9ea69 100644 --- a/plugins/importer-openapi/package-lock.json +++ b/plugins/importer-openapi/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-openapi", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, @@ -57,25 +57,27 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", - "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", + "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", "dependencies": { - "@types/node": "^22.0.0" + "@types/node": "^22.5.4" } }, "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "license": "MIT", "dependencies": { - "undici-types": "~6.18.2" + "undici-types": "~6.19.2" } }, "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/@yaakapp/cli": { "version": "0.0.42", diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index 3a6fc5241..71ce22ba3 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json index 5ec3241aa..f670c4321 100644 --- a/plugins/importer-postman/package-lock.json +++ b/plugins/importer-postman/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-postman", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.14" + "@yaakapp/api": "^0.2.5" }, "devDependencies": { "@types/node": "^20.14.9", @@ -664,25 +664,27 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", - "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", + "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", "dependencies": { - "@types/node": "^22.0.0" + "@types/node": "^22.5.4" } }, "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "license": "MIT", "dependencies": { - "undici-types": "~6.18.2" + "undici-types": "~6.19.2" } }, "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/@yaakapp/cli": { "version": "0.0.42", diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 41ef569d1..8bf5fd7ea 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -7,7 +7,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.14" + "@yaakapp/api": "^0.2.5" }, "devDependencies": { "@yaakapp/cli": "^0.0.42", diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json index 43241e860..788776b11 100644 --- a/plugins/importer-yaak/package-lock.json +++ b/plugins/importer-yaak/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-yaak", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.1.14" + "@yaakapp/api": "^0.2.5" }, "devDependencies": { "@types/node": "^20.14.9", @@ -395,25 +395,27 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", - "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", + "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", "dependencies": { - "@types/node": "^22.0.0" + "@types/node": "^22.5.4" } }, "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "license": "MIT", "dependencies": { - "undici-types": "~6.18.2" + "undici-types": "~6.19.2" } }, "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/@yaakapp/cli": { "version": "0.0.42", diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index db9e64f4d..0d6aceae8 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.1.14" + "@yaakapp/api": "^0.2.5" }, "devDependencies": { "@yaakapp/cli": "^0.0.42", diff --git a/plugins/template-function-response/package-lock.json b/plugins/template-function-response/package-lock.json index b0871814b..db9caadfe 100644 --- a/plugins/template-function-response/package-lock.json +++ b/plugins/template-function-response/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34" }, @@ -742,25 +742,27 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.15.tgz", - "integrity": "sha512-4nrImM9r4Afih0CcG6PWtGA6Luap/Ki5ZVl56WejWA8WPpy8AhEpC0KErpJChNzzqRjgK9ZEWdQNsBHppzAs8A==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", + "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", "dependencies": { - "@types/node": "^22.0.0" + "@types/node": "^22.5.4" } }, "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz", - "integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "license": "MIT", "dependencies": { - "undici-types": "~6.13.0" + "undici-types": "~6.19.2" } }, "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/@yaakapp/cli": { "version": "0.0.42", diff --git a/plugins/template-function-response/package.json b/plugins/template-function-response/package.json index cfad12360..632474ae2 100644 --- a/plugins/template-function-response/package.json +++ b/plugins/template-function-response/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.ts" }, "dependencies": { - "@yaakapp/api": "^0.1.14", + "@yaakapp/api": "^0.2.5", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34", "@xmldom/xmldom": "^0.8.10" diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts index 023707f1e..69e0145f3 100644 --- a/plugins/template-function-response/src/index.ts +++ b/plugins/template-function-response/src/index.ts @@ -1,10 +1,10 @@ import { DOMParser } from '@xmldom/xmldom'; -import { CallTemplateFunctionArgs, Context, HttpResponse, Plugin } from '@yaakapp/api'; +import { CallTemplateFunctionArgs, Context, HttpResponse, PluginDefinition } from '@yaakapp/api'; import { JSONPath } from 'jsonpath-plus'; import { readFileSync } from 'node:fs'; import xpath from 'xpath'; -export const plugin: Plugin = { +export const plugin: PluginDefinition = { templateFunctions: [{ name: 'response', args: [ From 035d7927f9bef913f2259009cad32515dde2de66 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 22 Sep 2024 11:09:18 -0700 Subject: [PATCH 038/996] Fix types --- plugins/exporter-curl/package-lock.json | 8 ++++---- plugins/exporter-curl/package.json | 2 +- plugins/filter-jsonpath/package-lock.json | 8 ++++---- plugins/filter-jsonpath/package.json | 2 +- plugins/filter-xpath/package-lock.json | 8 ++++---- plugins/filter-xpath/package.json | 2 +- plugins/importer-curl/package-lock.json | 8 ++++---- plugins/importer-curl/package.json | 2 +- plugins/importer-curl/src/index.ts | 6 +++--- plugins/importer-curl/tests/index.test.ts | 4 ++-- plugins/importer-insomnia/package-lock.json | 8 ++++---- plugins/importer-insomnia/package.json | 2 +- plugins/importer-openapi/package-lock.json | 8 ++++---- plugins/importer-openapi/package.json | 2 +- plugins/importer-postman/package-lock.json | 8 ++++---- plugins/importer-postman/package.json | 2 +- plugins/importer-postman/src/index.ts | 9 ++++----- plugins/importer-yaak/package-lock.json | 8 ++++---- plugins/importer-yaak/package.json | 2 +- plugins/template-function-response/package-lock.json | 8 ++++---- plugins/template-function-response/package.json | 2 +- 21 files changed, 54 insertions(+), 55 deletions(-) diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json index 6da045bfc..30fda584b 100644 --- a/plugins/exporter-curl/package-lock.json +++ b/plugins/exporter-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "exporter-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.2.5" + "@yaakapp/api": "^0.2.7" }, "devDependencies": { "@types/node": "^20.14.9", @@ -702,9 +702,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", - "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", + "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index 7dbbe30b6..8dc1fec2e 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.2.5" + "@yaakapp/api": "^0.2.7" }, "devDependencies": { "@types/node": "^20.14.9", diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json index 36b80dc2a..755b6e1a0 100644 --- a/plugins/filter-jsonpath/package-lock.json +++ b/plugins/filter-jsonpath/package-lock.json @@ -8,7 +8,7 @@ "name": "filter-jsonpath", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "jsonpath-plus": "^9.0.0" }, "devDependencies": { @@ -49,9 +49,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", - "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", + "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index 4485f0716..1b95ab941 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "jsonpath-plus": "^9.0.0", - "@yaakapp/api": "^0.2.5" + "@yaakapp/api": "^0.2.7" }, "devDependencies": { "@yaakapp/cli": "^0.0.42", diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json index 4e27df34b..7601a55ea 100644 --- a/plugins/filter-xpath/package-lock.json +++ b/plugins/filter-xpath/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "xpath": "^0.0.34" }, "devDependencies": { @@ -36,9 +36,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", - "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", + "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index 7018698cf..b8d380348 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "@xmldom/xmldom": "^0.8.10", "xpath": "^0.0.34" }, diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json index 686d0c673..b03a98f34 100644 --- a/plugins/importer-curl/package-lock.json +++ b/plugins/importer-curl/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-curl", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "shell-quote": "^1.8.1" }, "devDependencies": { @@ -710,9 +710,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", - "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", + "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index 41fcc851e..b6dc6ccd8 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "shell-quote": "^1.8.1" }, "devDependencies": { diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts index 87b6f40e7..00cb4ca60 100644 --- a/plugins/importer-curl/src/index.ts +++ b/plugins/importer-curl/src/index.ts @@ -1,4 +1,4 @@ -import { Environment, Folder, HttpRequest, HttpUrlParameter, Model, Workspace, Context } from '@yaakapp/api'; +import { Context, Environment, Folder, HttpRequest, HttpUrlParameter, Workspace } from '@yaakapp/api'; import { ControlOperator, parse, ParseEntry } from 'shell-quote'; type AtLeast = Partial & Pick; @@ -405,9 +405,9 @@ function splitOnce(str: string, sep: string): string[] { return [str]; } -const idCount: Partial> = {}; +const idCount: Partial> = {}; -function generateId(model: Model['model']): string { +function generateId(model: string): string { idCount[model] = (idCount[model] ?? -1) + 1; return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`; } diff --git a/plugins/importer-curl/tests/index.test.ts b/plugins/importer-curl/tests/index.test.ts index b0fa10282..bb5362124 100644 --- a/plugins/importer-curl/tests/index.test.ts +++ b/plugins/importer-curl/tests/index.test.ts @@ -1,4 +1,4 @@ -import { Context, HttpRequest, Model, Workspace } from '@yaakapp/api'; +import { Context, HttpRequest, Workspace } from '@yaakapp/api'; import { describe, expect, test } from 'vitest'; import { pluginHookImport } from '../src'; @@ -307,7 +307,7 @@ describe('importer-curl', () => { }); }); -const idCount: Partial> = {}; +const idCount: Partial> = {}; function baseRequest(mergeWith: Partial) { idCount.http_request = (idCount.http_request ?? -1) + 1; diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json index a1c7febd4..188b1e891 100644 --- a/plugins/importer-insomnia/package-lock.json +++ b/plugins/importer-insomnia/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-insomnia", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "yaml": "^2.4.2" }, "devDependencies": { @@ -27,9 +27,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", - "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", + "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 1bc2ad034..fe036c658 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "yaml": "^2.4.2" }, "devDependencies": { diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json index 013c9ea69..8b0a552e7 100644 --- a/plugins/importer-openapi/package-lock.json +++ b/plugins/importer-openapi/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-openapi", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, @@ -57,9 +57,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", - "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", + "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index 71ce22ba3..1c151b508 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" }, diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json index f670c4321..50df57fbb 100644 --- a/plugins/importer-postman/package-lock.json +++ b/plugins/importer-postman/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-postman", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.2.5" + "@yaakapp/api": "^0.2.7" }, "devDependencies": { "@types/node": "^20.14.9", @@ -664,9 +664,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", - "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", + "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index 8bf5fd7ea..0664e7648 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -7,7 +7,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.2.5" + "@yaakapp/api": "^0.2.7" }, "devDependencies": { "@yaakapp/cli": "^0.0.42", diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts index 229901d04..b4376aa90 100644 --- a/plugins/importer-postman/src/index.ts +++ b/plugins/importer-postman/src/index.ts @@ -1,12 +1,11 @@ import { + Context, Environment, Folder, HttpRequest, HttpRequestHeader, - Model, - Workspace, - Context, HttpUrlParameter, + Workspace, } from '@yaakapp/api'; const POSTMAN_2_1_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'; @@ -327,9 +326,9 @@ function convertTemplateSyntax(obj: T): T { } } -const idCount: Partial> = {}; +const idCount: Partial> = {}; -function generateId(model: Model['model']): string { +function generateId(model: string): string { idCount[model] = (idCount[model] ?? -1) + 1; return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`; } diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json index 788776b11..e3f9002d5 100644 --- a/plugins/importer-yaak/package-lock.json +++ b/plugins/importer-yaak/package-lock.json @@ -8,7 +8,7 @@ "name": "importer-yaak", "version": "0.0.1", "dependencies": { - "@yaakapp/api": "^0.2.5" + "@yaakapp/api": "^0.2.7" }, "devDependencies": { "@types/node": "^20.14.9", @@ -395,9 +395,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", - "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", + "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index 0d6aceae8..84bda6488 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.js" }, "dependencies": { - "@yaakapp/api": "^0.2.5" + "@yaakapp/api": "^0.2.7" }, "devDependencies": { "@yaakapp/cli": "^0.0.42", diff --git a/plugins/template-function-response/package-lock.json b/plugins/template-function-response/package-lock.json index db9caadfe..1ce99e566 100644 --- a/plugins/template-function-response/package-lock.json +++ b/plugins/template-function-response/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34" }, @@ -742,9 +742,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.5.tgz", - "integrity": "sha512-UXD4Vvm4IVGNqKQuORnlbZ/RSOqA3AkkvaBqcipqGCodkx/4kM1602fBFfBZMdiouq0RyyQ65ByWvJWVre/adg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", + "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/plugins/template-function-response/package.json b/plugins/template-function-response/package.json index 632474ae2..fcf7c537c 100644 --- a/plugins/template-function-response/package.json +++ b/plugins/template-function-response/package.json @@ -6,7 +6,7 @@ "build": "yaakcli build ./src/index.ts" }, "dependencies": { - "@yaakapp/api": "^0.2.5", + "@yaakapp/api": "^0.2.7", "jsonpath-plus": "^9.0.0", "xpath": "^0.0.34", "@xmldom/xmldom": "^0.8.10" From 9df586cb59e9bb6ad556e6b5b8bc761fcae6069c Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 30 Sep 2024 18:11:51 -0700 Subject: [PATCH 039/996] NPM workspaces --- package-lock.json | 5836 +++++++++++++++-- package.json | 13 +- plugins/exporter-curl/package-lock.json | 1657 ----- plugins/exporter-curl/package.json | 12 +- plugins/exporter-curl/src/index.ts | 1 + plugins/filter-jsonpath/package-lock.json | 8 +- plugins/filter-jsonpath/package.json | 10 +- plugins/filter-xpath/package-lock.json | 8 +- plugins/filter-xpath/package.json | 9 +- plugins/importer-curl/package-lock.json | 8 +- plugins/importer-curl/package.json | 11 +- plugins/importer-insomnia/package-lock.json | 8 +- plugins/importer-insomnia/package.json | 9 +- plugins/importer-openapi/package-lock.json | 8 +- plugins/importer-openapi/package.json | 10 +- plugins/importer-postman/package-lock.json | 2 +- plugins/importer-postman/package.json | 13 +- plugins/importer-yaak/package-lock.json | 2 +- plugins/importer-yaak/package.json | 12 +- .../package-lock.json | 2 +- .../template-function-response/package.json | 10 +- types/models.ts | 213 - 22 files changed, 5504 insertions(+), 2358 deletions(-) delete mode 100644 plugins/exporter-curl/package-lock.json delete mode 100644 types/models.ts diff --git a/package-lock.json b/package-lock.json index 9ac01b9a6..bb2fd18f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,10 +5,18 @@ "packages": { "": { "name": "@yaakapp/plugins", + "workspaces": [ + "plugins/*" + ], + "dependencies": { + "@yaakapp/api": "^0.2.9" + }, "devDependencies": { + "@types/node": "^22.7.4", "jsonpath": "^1.1.1", - "typescript": "^5.5.2", - "vitest": "^2.0.4" + "typescript": "^5.6.2", + "vitest": "^2.0.4", + "workspaces-run": "^1.0.2" } }, "node_modules/@ampproject/remapping": { @@ -24,6 +32,121 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-0.4.0.tgz", + "integrity": "sha512-TclHHKDVYQ8rJGZgVeWiF7c91yWzTTWdPagltgutelGu/Psup5PQlUq6svx7S8suj+jXcaE34yEEsfIvzXXB2Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -392,6 +515,18 @@ "node": ">=12" } }, + "node_modules/@exodus/schemasafe": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", + "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==", + "license": "MIT" + }, + "node_modules/@faker-js/faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-R11tGE6yIFwqpaIqcfkcg7AICXzFg14+5h5v0TfF/9+RMDL6jhzCy/pxHVOfbALGdtVYdt6JdR21tuxEgl34dw==", + "license": "MIT" + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -440,6 +575,54 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsep-plugin/assignment": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.2.1.tgz", + "integrity": "sha512-gaHqbubTi29aZpVbBlECRpmdia+L5/lh2BwtIJTmtxdbecEyyX/ejAOg7eQDGNvGOUmPY7Z2Yxdy9ioyH/VJeA==", + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@jsep-plugin/regex": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", + "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.19.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", @@ -654,6 +837,54 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/jsonpath": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.4.tgz", + "integrity": "sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.7.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz", + "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, "node_modules/@vitest/expect": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.4.tgz", @@ -735,581 +966,4414 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=10.0.0" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "node_modules/@yaakapp/api": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.9.tgz", + "integrity": "sha512-0l6kfLWDqf0eKFeGE/8xKtqDNH/30YUPL9QW4ZvIB+daVqfhrJ/5V0JMR+g1atU+EXBe2E/WViaQmcK5lgBOng==", + "dependencies": { + "@types/node": "^22.5.4" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/chai": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", - "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", - "dev": true, + "node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "license": "MIT", "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=12" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, - "engines": { - "node": ">= 16" + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "ajv": "^8.0.0" }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=8" } }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=6.0" + "node": ">=8" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, + "license": "MIT", "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "node": ">=0.10.0" } }, - "node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, + "license": "MIT", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" }, "engines": { - "node": ">=4.0" + "node": ">= 0.4" }, - "optionalDependencies": { - "source-map": "~0.6.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escodegen/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esprima": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", - "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "license": "MIT", + "dependencies": { + "array-uniq": "^1.0.1" }, "engines": { - "node": ">=0.4.0" + "node": ">=0.10.0" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0" + "node": ">=0.10.0" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, + "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" }, "engines": { - "node": ">=16.17" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "license": "MIT", "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=0.10.0" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "engines": { - "node": "*" + "node": ">=12" } }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "license": "MIT" + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true, + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, "engines": { - "node": ">=16.17.0" + "node": ">= 4.5.0" } }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" }, - "node_modules/jsonpath": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", - "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, + "license": "MIT", "dependencies": { - "esprima": "1.2.2", - "static-eval": "2.0.2", - "underscore": "1.12.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, + "license": "MIT", "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "is-descriptor": "^1.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=0.10.0" } }, - "node_modules/loupe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", - "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { - "get-func-name": "^2.0.1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" + "license": "MIT", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=0.10.0" } }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, + "license": "MIT", "dependencies": { - "path-key": "^4.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "license": "MIT" + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, + "license": "MIT", "dependencies": { - "mimic-fn": "^4.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" }, "engines": { - "node": ">=12" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", "dev": true, "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=12" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { "node": ">=8" } }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true + "node_modules/charset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/charset/-/charset-1.0.1.tgz", + "integrity": "sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } }, - "node_modules/pathval": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", - "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, "engines": { - "node": ">= 14.16" + "node": ">= 16" } }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "node_modules/chunkd": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", + "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", + "dev": true, + "license": "MIT" }, - "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/compute-gcd": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", + "integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==", + "dependencies": { + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, + "node_modules/compute-lcm": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz", + "integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==", + "dependencies": { + "compute-gcd": "^1.2.1", + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } - ], + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha512-+AWBwjGadtksxjOQSFDhPNQbed7icNXApT4+2BNpsXzcCBiInq2H9XW0O8sfHFaPmnQRs7cg/P0fAr2IWQSW0g==", + "dev": true, + "license": "BSD", + "dependencies": { + "readable-stream": "~1.1.9" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/exporter-curl": { + "resolved": "plugins/exporter-curl", + "link": true + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/fast-glob/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/filter-jsonpath": { + "resolved": "plugins/filter-jsonpath", + "link": true + }, + "node_modules/filter-xpath": { + "resolved": "plugins/filter-xpath", + "link": true + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreach": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", + "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==", + "license": "MIT" + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-workspaces": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/get-workspaces/-/get-workspaces-0.5.2.tgz", + "integrity": "sha512-99x72taQ9OUHhCmBS0B2WI/zwOtBOBPoyVNGs9+B0ag2GGhCjl/EaU9VQ8Zorx64TyVj1Am7bO+0J1KwDqo7OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^0.4.0", + "fs-extra": "^7.0.1", + "globby": "^9.2.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", + "dev": true, + "license": "BSD" + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphlib": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/http-reasons": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/http-reasons/-/http-reasons-0.1.0.tgz", + "integrity": "sha512-P6kYh0lKZ+y29T2Gqz+RlC9WBLhKe8kDmcJ+A+611jFfxdPsbMRQ5aNmFRM3lENqFkK+HTTL+tlQviAiv0AbLQ==", + "license": "Apache-2.0" + }, + "node_modules/http2-client": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", + "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==", + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/importer-curl": { + "resolved": "plugins/importer-curl", + "link": true + }, + "node_modules/importer-insomnia": { + "resolved": "plugins/importer-insomnia", + "link": true + }, + "node_modules/importer-openapi": { + "resolved": "plugins/importer-openapi", + "link": true + }, + "node_modules/importer-postman": { + "resolved": "plugins/importer-postman", + "link": true + }, + "node_modules/importer-yaak": { + "resolved": "plugins/importer-yaak", + "link": true + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsep": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.9.tgz", + "integrity": "sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==", + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-pointer": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.2.tgz", + "integrity": "sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==", + "license": "MIT", + "dependencies": { + "foreach": "^2.0.4" + } + }, + "node_modules/json-schema-compare": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", + "integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.4" + } + }, + "node_modules/json-schema-merge-allof": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", + "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", + "license": "MIT", + "dependencies": { + "compute-lcm": "^1.1.2", + "json-schema-compare": "^0.2.2", + "lodash": "^4.17.20" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "dev": true, + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/jsonpath-plus": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-9.0.0.tgz", + "integrity": "sha512-bqE77VIDStrOTV/czspZhTn+o27Xx9ZJRGVkdVShEtPoqsIx5yALv3lWVU6y+PqYvWPJNWE7ORCQheQkEe0DDA==", + "license": "MIT", + "dependencies": { + "@jsep-plugin/assignment": "^1.2.1", + "@jsep-plugin/regex": "^1.0.3", + "jsep": "^1.3.8" + }, + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/liquid-json": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/liquid-json/-/liquid-json-0.3.1.tgz", + "integrity": "sha512-wUayTU8MS827Dam6MxgD72Ui+KOSF+u/eIqpatOtjnvgJ0+mnDq33uC2M7J0tPK+upe/DpUAuK4JUU89iBoNKQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", + "integrity": "sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-format": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mime-format/-/mime-format-2.0.1.tgz", + "integrity": "sha512-XxU3ngPbEnrYnNbIX+lYSaYg0M01v6p2ntd2YaFksTu0vayaw5OJvbdRyWs07EYRlLED5qadUZ+xo+XhOvFhwg==", + "license": "Apache-2.0", + "dependencies": { + "charset": "^1.0.0" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/neotraverse": { + "version": "0.6.15", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.15.tgz", + "integrity": "sha512-HZpdkco+JeXq0G+WWpMJ4NsX3pqb5O7eR9uGz3FfoFt+LYzU8iRWp49nJtud6hsDoywM8tIrDo3gjgmOqJA8LA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch-h2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz", + "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==", + "license": "MIT", + "dependencies": { + "http2-client": "^1.2.5" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-readfiles": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", + "integrity": "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==", + "license": "MIT", + "dependencies": { + "es6-promise": "^3.2.1" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/oas-kit-common": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", + "integrity": "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==", + "license": "BSD-3-Clause", + "dependencies": { + "fast-safe-stringify": "^2.0.7" + } + }, + "node_modules/oas-linter": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/oas-linter/-/oas-linter-3.2.2.tgz", + "integrity": "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@exodus/schemasafe": "^1.0.0-rc.2", + "should": "^13.2.1", + "yaml": "^1.10.0" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-linter/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/oas-resolver": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", + "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", + "license": "BSD-3-Clause", + "dependencies": { + "node-fetch-h2": "^2.3.0", + "oas-kit-common": "^1.0.8", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + }, + "bin": { + "resolve": "resolve.js" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-resolver-browser": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/oas-resolver-browser/-/oas-resolver-browser-2.5.6.tgz", + "integrity": "sha512-Jw5elT/kwUJrnGaVuRWe1D7hmnYWB8rfDDjBnpQ+RYY/dzAewGXeTexXzt4fGEo6PUE4eqKqPWF79MZxxvMppA==", + "license": "BSD-3-Clause", + "dependencies": { + "node-fetch-h2": "^2.3.0", + "oas-kit-common": "^1.0.8", + "path-browserify": "^1.0.1", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + }, + "bin": { + "resolve": "resolve.js" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-resolver-browser/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/oas-resolver/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/oas-schema-walker": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", + "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==", + "license": "BSD-3-Clause", + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-validator": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", + "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", + "license": "BSD-3-Clause", + "dependencies": { + "call-me-maybe": "^1.0.1", + "oas-kit-common": "^1.0.8", + "oas-linter": "^3.2.2", + "oas-resolver": "^2.5.6", + "oas-schema-walker": "^1.1.5", + "reftools": "^1.1.9", + "should": "^13.2.1", + "yaml": "^1.10.0" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-validator/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openapi-to-postmanv2": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/openapi-to-postmanv2/-/openapi-to-postmanv2-4.24.0.tgz", + "integrity": "sha512-SfWo8fftwTVmBs61ZY9SciNlQ7ddSBmPS7NTBdf+LyjHdzr2/TNuvFjyftGJ7Jnm48oghi+R9At2geq1NoBOLA==", + "license": "Apache-2.0", + "dependencies": { + "ajv": "8.11.0", + "ajv-draft-04": "1.0.0", + "ajv-formats": "2.1.1", + "async": "3.2.4", + "commander": "2.20.3", + "graphlib": "2.1.8", + "js-yaml": "4.1.0", + "json-pointer": "0.6.2", + "json-schema-merge-allof": "0.8.1", + "lodash": "4.17.21", + "neotraverse": "0.6.15", + "oas-resolver-browser": "2.5.6", + "object-hash": "3.0.0", + "path-browserify": "1.0.1", + "postman-collection": "^4.4.0", + "swagger2openapi": "7.0.8", + "yaml": "1.10.2" + }, + "bin": { + "openapi2postmanv2": "bin/openapi2postmanv2.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/openapi-to-postmanv2/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "license": "MIT" + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/physical-cpu-count": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz", + "integrity": "sha512-rxJOljMuWtYlvREBmd6TZYanfcPhNUKtGDZBjBBS8WG1dpN2iwPsRJZgQqN/OtJuiQckdRFOfzogqJClTrsi7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postman-collection": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.5.0.tgz", + "integrity": "sha512-152JSW9pdbaoJihwjc7Q8lc3nPg/PC9lPTHdMk7SHnHhu/GBJB7b2yb9zG7Qua578+3PxkQ/HYBuXpDSvsf7GQ==", + "license": "Apache-2.0", + "dependencies": { + "@faker-js/faker": "5.5.3", + "file-type": "3.9.0", + "http-reasons": "0.1.0", + "iconv-lite": "0.6.3", + "liquid-json": "0.3.1", + "lodash": "4.17.21", + "mime-format": "2.0.1", + "mime-types": "2.1.35", + "postman-url-encoder": "3.0.5", + "semver": "7.6.3", + "uuid": "8.3.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/postman-url-encoder": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postman-url-encoder/-/postman-url-encoder-3.0.5.tgz", + "integrity": "sha512-jOrdVvzUXBC7C+9gkIkpDJ3HIxOHTIqjpQ4C1EMt1ZGeMvSEpbFCKq23DEfgsj46vMnDgyQf+1ZLp2Wm+bKSsA==", + "license": "Apache-2.0", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reftools": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", + "integrity": "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==", + "license": "BSD-3-Clause", + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true, + "license": "MIT" + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/rollup": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", + "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.19.0", + "@rollup/rollup-android-arm64": "4.19.0", + "@rollup/rollup-darwin-arm64": "4.19.0", + "@rollup/rollup-darwin-x64": "4.19.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", + "@rollup/rollup-linux-arm-musleabihf": "4.19.0", + "@rollup/rollup-linux-arm64-gnu": "4.19.0", + "@rollup/rollup-linux-arm64-musl": "4.19.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", + "@rollup/rollup-linux-riscv64-gnu": "4.19.0", + "@rollup/rollup-linux-s390x-gnu": "4.19.0", + "@rollup/rollup-linux-x64-gnu": "4.19.0", + "@rollup/rollup-linux-x64-musl": "4.19.0", + "@rollup/rollup-win32-arm64-msvc": "4.19.0", + "@rollup/rollup-win32-ia32-msvc": "4.19.0", + "@rollup/rollup-win32-x64-msvc": "4.19.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/should": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", + "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", + "license": "MIT", + "dependencies": { + "should-equal": "^2.0.0", + "should-format": "^3.0.3", + "should-type": "^1.4.0", + "should-type-adaptors": "^1.0.1", + "should-util": "^1.0.0" + } + }, + "node_modules/should-equal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", + "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", + "license": "MIT", + "dependencies": { + "should-type": "^1.4.0" + } + }, + "node_modules/should-format": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", + "license": "MIT", + "dependencies": { + "should-type": "^1.3.0", + "should-type-adaptors": "^1.0.1" + } + }, + "node_modules/should-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", + "license": "MIT" + }, + "node_modules/should-type-adaptors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", + "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", + "license": "MIT", + "dependencies": { + "should-type": "^1.3.0", + "should-util": "^1.0.0" + } + }, + "node_modules/should-util": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", + "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", + "license": "MIT" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=0.10.0" } }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, "engines": { - "node": ">= 0.8.0" + "node": ">=0.10.0" } }, - "node_modules/rollup": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", - "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "is-descriptor": "^1.0.0" }, - "bin": { - "rollup": "dist/bin/rollup" + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.2.0" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.19.0", - "@rollup/rollup-android-arm64": "4.19.0", - "@rollup/rollup-darwin-arm64": "4.19.0", - "@rollup/rollup-darwin-x64": "4.19.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", - "@rollup/rollup-linux-arm-musleabihf": "4.19.0", - "@rollup/rollup-linux-arm64-gnu": "4.19.0", - "@rollup/rollup-linux-arm64-musl": "4.19.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", - "@rollup/rollup-linux-riscv64-gnu": "4.19.0", - "@rollup/rollup-linux-s390x-gnu": "4.19.0", - "@rollup/rollup-linux-x64-gnu": "4.19.0", - "@rollup/rollup-linux-x64-musl": "4.19.0", - "@rollup/rollup-win32-arm64-msvc": "4.19.0", - "@rollup/rollup-win32-ia32-msvc": "4.19.0", - "@rollup/rollup-win32-x64-msvc": "4.19.0", - "fsevents": "~2.3.2" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { - "shebang-regex": "^3.0.0" + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/siginfo": { + "node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true, + "license": "BSD-3-Clause", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=0.10.0" } }, "node_modules/source-map": { @@ -1331,6 +5395,138 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "license": "MIT", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true, + "license": "MIT" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-0.1.2.tgz", + "integrity": "sha512-t6JTeWbon5yYazpiZN1Fn0ehh5h/FBH9iuoQBAaEHUp+uFxLKFrmMQF3ElmzoScD9OQn+gb8Ut+NOuQYZ1aBfA==", + "dev": true, + "license": "ISC", + "dependencies": { + "through2": "~0.4.1" + } + }, + "node_modules/split2/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/split2/node_modules/object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==", + "dev": true, + "license": "MIT" + }, + "node_modules/split2/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/split2/node_modules/through2": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", + "integrity": "sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.17", + "xtend": "~2.1.1" + } + }, + "node_modules/split2/node_modules/xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -1346,12 +5542,138 @@ "escodegen": "^1.8.1" } }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", "dev": true }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -1364,6 +5686,130 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/swagger2openapi": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/swagger2openapi/-/swagger2openapi-7.0.8.tgz", + "integrity": "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==", + "license": "BSD-3-Clause", + "dependencies": { + "call-me-maybe": "^1.0.1", + "node-fetch": "^2.6.1", + "node-fetch-h2": "^2.3.0", + "node-readfiles": "^0.2.0", + "oas-kit-common": "^1.0.8", + "oas-resolver": "^2.5.6", + "oas-schema-walker": "^1.1.5", + "oas-validator": "^5.0.8", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + }, + "bin": { + "boast": "boast.js", + "oas-validate": "oas-validate.js", + "swagger2openapi": "swagger2openapi.js" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/swagger2openapi/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/task-graph-runner": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/task-graph-runner/-/task-graph-runner-1.0.3.tgz", + "integrity": "sha512-aC70bepv1j9jXX70nzolNvnHJvD4A3WtU4lQ1HEjgTS8rgnRXoUUq+xl9hZ1hKYXxVwElZXmUUMxpzDC6R0mRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.0.3" + } + }, + "node_modules/template-function-request": { + "resolved": "plugins/template-function-request", + "link": true + }, + "node_modules/template-function-response": { + "resolved": "plugins/template-function-response", + "link": true + }, + "node_modules/through2": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", + "integrity": "sha512-zexCrAOTbjkBCXGyozn7hhS3aEaqdrc59mAD2E3dKYzV1vFuEGQ1hEDJN2oQMQFwy4he2zyLqPZV+AlfS8ZWJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.17", + "xtend": "~3.0.0" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, "node_modules/tinybench": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", @@ -1397,6 +5843,77 @@ "node": ">=14.0.0" } }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -1409,11 +5926,102 @@ "node": ">= 0.8.0" } }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1422,12 +6030,209 @@ "node": ">=14.17" } }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/underscore": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", "dev": true }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true, + "license": "MIT" + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate.io-array": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz", + "integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==", + "license": "MIT" + }, + "node_modules/validate.io-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz", + "integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==" + }, + "node_modules/validate.io-integer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz", + "integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==", + "dependencies": { + "validate.io-number": "^1.0.3" + } + }, + "node_modules/validate.io-integer-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz", + "integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==", + "dependencies": { + "validate.io-array": "^1.0.3", + "validate.io-integer": "^1.0.4" + } + }, + "node_modules/validate.io-number": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz", + "integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg==" + }, "node_modules/vite": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", @@ -1569,6 +6374,22 @@ } } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -1584,6 +6405,43 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", @@ -1608,6 +6466,208 @@ "engines": { "node": ">=0.10.0" } + }, + "node_modules/workspaces-run": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/workspaces-run/-/workspaces-run-1.0.2.tgz", + "integrity": "sha512-VJO+ZcefRGjH81hxGOpS/bpelW+l6PfjUlA8cqtSq/hbIlTC+oG9TWUJTo1xKIyRSg/W+Snu2g9V0lyWGbpCgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.1", + "chalk": "^3.0.0", + "chunkd": "^2.0.1", + "cross-spawn": "^7.0.1", + "get-workspaces": "^0.5.2", + "meow": "^6.0.0", + "micromatch": "^4.0.2", + "p-limit": "^2.2.1", + "physical-cpu-count": "^2.0.0", + "redent": "^3.0.0", + "semver": "^7.1.1", + "signal-exit": "^3.0.2", + "task-graph-runner": "^1.0.3", + "trim-newlines": "^3.0.0", + "wrapline": "^2.0.1" + }, + "bin": { + "workspaces-run": "bin.js" + } + }, + "node_modules/workspaces-run/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrapline": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wrapline/-/wrapline-2.0.1.tgz", + "integrity": "sha512-WmC0Dk43usmD+shMS8dr06Znblx3nAWHWR+BMecQEClNq/NTBPKIA6JHSX+cv8TRG7w4H6/nLGUmFt56rHkFow==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer2": "~0.0.2", + "split2": "^0.1.2", + "through2": "^0.5.1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xpath": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", + "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==", + "license": "MIT", + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha512-sp/sT9OALMjRW1fKDlPeuSZlDQpkqReA0pyJukniWbTGoEKefHxhGJynE3PNhUMlcM8qWIjPwecwCw4LArS5Eg==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "plugins/exporter-curl": { + "version": "0.0.1" + }, + "plugins/filter-jsonpath": { + "version": "0.0.1", + "dependencies": { + "jsonpath-plus": "^9.0.0" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } + }, + "plugins/filter-xpath": { + "version": "0.0.1", + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "xpath": "^0.0.34" + } + }, + "plugins/importer-curl": { + "version": "0.0.1", + "dependencies": { + "shell-quote": "^1.8.1" + } + }, + "plugins/importer-insomnia": { + "version": "0.0.1", + "dependencies": { + "yaml": "^2.4.2" + } + }, + "plugins/importer-openapi": { + "version": "0.0.1", + "dependencies": { + "openapi-to-postmanv2": "^4.23.1", + "yaml": "^2.4.2" + } + }, + "plugins/importer-postman": { + "version": "0.0.1" + }, + "plugins/importer-yaak": { + "version": "0.0.1" + }, + "plugins/template-function-request": { + "version": "0.0.1", + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "jsonpath-plus": "^9.0.0", + "xpath": "^0.0.34" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } + }, + "plugins/template-function-response": { + "version": "0.0.1", + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "jsonpath-plus": "^9.0.0", + "xpath": "^0.0.34" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } } } } diff --git a/package.json b/package.json index d535aa6f6..500caa6cc 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,24 @@ { "name": "@yaakapp/plugins", "repository": "https://github.com/yaakapp/plugins", + "workspaces": [ + "plugins/*" + ], "private": true, "scripts": { - "build": "node scripts/build-plugins.cjs", + "build": "workspaces-run --parallel -- npm run --workspaces build", + "dev": "workspaces-run --parallel -- npm run --workspaces dev", "test": "vitest run", "lint": "tsc" }, "devDependencies": { + "@types/node": "^22.7.4", "jsonpath": "^1.1.1", + "typescript": "^5.6.2", "vitest": "^2.0.4", - "typescript": "^5.5.2" + "workspaces-run": "^1.0.2" + }, + "dependencies": { + "@yaakapp/api": "^0.2.9" } } diff --git a/plugins/exporter-curl/package-lock.json b/plugins/exporter-curl/package-lock.json deleted file mode 100644 index 30fda584b..000000000 --- a/plugins/exporter-curl/package-lock.json +++ /dev/null @@ -1,1657 +0,0 @@ -{ - "name": "exporter-curl", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "exporter-curl", - "version": "0.0.1", - "dependencies": { - "@yaakapp/api": "^0.2.7" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "@yaakapp/cli": "^0.0.42", - "typescript": "^5.5.2", - "vitest": "^1.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@vitest/expect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", - "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", - "dev": true, - "dependencies": { - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "chai": "^4.3.10" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", - "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", - "dev": true, - "dependencies": { - "@vitest/utils": "1.6.0", - "p-limit": "^5.0.0", - "pathe": "^1.1.1" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", - "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", - "dev": true, - "dependencies": { - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "pretty-format": "^29.7.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", - "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", - "dev": true, - "dependencies": { - "tinyspy": "^2.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", - "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", - "dev": true, - "dependencies": { - "diff-sequences": "^29.6.3", - "estree-walker": "^3.0.3", - "loupe": "^2.3.7", - "pretty-format": "^29.7.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@yaakapp/api": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", - "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", - "dependencies": { - "@types/node": "^22.5.4" - } - }, - "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/@yaakapp/cli": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", - "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "yaakcli": "bin/cli.js" - }, - "optionalDependencies": { - "@yaakapp/cli-darwin-arm64": "0.0.42", - "@yaakapp/cli-darwin-x64": "0.0.42", - "@yaakapp/cli-linux-x64": "0.0.42", - "@yaakapp/cli-win32-x64": "0.0.42" - } - }, - "node_modules/@yaakapp/cli-darwin-arm64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", - "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-darwin-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", - "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-linux-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", - "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yaakapp/cli-win32-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", - "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-styles": { - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/confbox": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", - "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", - "dev": true - }, - "node_modules/local-pkg": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", - "dev": true, - "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mlly": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.0.tgz", - "integrity": "sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==", - "dev": true, - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.1.0", - "ufo": "^1.5.3" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/pkg-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz", - "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==", - "dev": true, - "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.6.1", - "pathe": "^1.1.2" - } - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true - }, - "node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true - }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", - "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", - "dev": true, - "dependencies": { - "js-tokens": "^9.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/tinybench": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", - "dev": true - }, - "node_modules/tinypool": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", - "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", - "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", - "dev": true - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/vite": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", - "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", - "dev": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", - "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", - "dev": true, - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vitest": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", - "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", - "dev": true, - "dependencies": { - "@vitest/expect": "1.6.0", - "@vitest/runner": "1.6.0", - "@vitest/snapshot": "1.6.0", - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "acorn-walk": "^8.3.2", - "chai": "^4.3.10", - "debug": "^4.3.4", - "execa": "^8.0.1", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.5.0", - "strip-literal": "^2.0.0", - "tinybench": "^2.5.1", - "tinypool": "^0.8.3", - "vite": "^5.0.0", - "vite-node": "1.6.0", - "why-is-node-running": "^2.2.2" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.6.0", - "@vitest/ui": "1.6.0", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/why-is-node-running": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", - "dev": true, - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index 8dc1fec2e..60ae346b0 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -3,15 +3,7 @@ "private": true, "version": "0.0.1", "scripts": { - "build": "yaakcli build ./src/index.js" - }, - "dependencies": { - "@yaakapp/api": "^0.2.7" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "typescript": "^5.5.2", - "vitest": "^1.4.0", - "@yaakapp/cli": "^0.0.42" + "build": "yaakcli build ./src/index.js", + "dev": "yaakcli dev ./src/index.js" } } diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts index 2bf3b7afe..97814c823 100644 --- a/plugins/exporter-curl/src/index.ts +++ b/plugins/exporter-curl/src/index.ts @@ -23,6 +23,7 @@ export async function pluginHookExport(_ctx: Context, request: Partial; - authenticationType: string | null; - metadata: GrpcMetadataEntry[]; -} - -export interface GrpcEvent extends BaseModel { - readonly workspaceId: string; - readonly requestId: string; - readonly connectionId: string; - readonly model: 'grpc_event'; - content: string; - status: number | null; - error: string | null; - eventType: - | 'info' - | 'error' - | 'client_message' - | 'server_message' - | 'connection_start' - | 'connection_end'; - metadata: Record; -} - -export interface GrpcConnection extends BaseModel { - readonly workspaceId: string; - readonly requestId: string; - readonly model: 'grpc_connection'; - service: string; - method: string; - elapsed: number; - elapsedConnection: number; - status: number; - url: string; - error: string | null; - trailers: Record; -} - -export interface HttpRequest extends BaseModel { - readonly workspaceId: string; - readonly model: 'http_request'; - folderId: string | null; - sortPriority: number; - name: string; - url: string; - urlParameters: HttpUrlParameter[]; - body: Record; - bodyType: string | null; - authentication: Record; - authenticationType: string | null; - method: string; - headers: HttpHeader[]; -} - -export interface KeyValue extends Omit { - readonly model: 'key_value'; - readonly key: string; - readonly namespace: string; - value: string; -} - -export interface HttpResponse extends BaseModel { - readonly workspaceId: string; - readonly model: 'http_response'; - readonly requestId: string; - readonly bodyPath: string | null; - readonly contentLength: number | null; - readonly error: string; - readonly status: number; - readonly elapsed: number; - readonly elapsedHeaders: number; - readonly statusReason: string; - readonly version: string; - readonly remoteAddr: string; - readonly url: string; - readonly headers: HttpHeader[]; -} - -export function isResponseLoading(response: HttpResponse | GrpcConnection): boolean { - return response.elapsed === 0; -} - -export function modelsEq(a: Model, b: Model) { - if (a.model === 'key_value' && b.model === 'key_value') { - return a.key === b.key && a.namespace === b.namespace; - } - if ('id' in a && 'id' in b) { - return a.id === b.id; - } - return false; -} - -export function getContentTypeHeader(headers: HttpHeader[]): string | null { - return headers.find((h) => h.name.toLowerCase() === 'content-type')?.value ?? null; -} From 54689d19eff4e1750adfcec161c6ebfc3ae37a50 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 2 Oct 2024 06:56:07 -0700 Subject: [PATCH 040/996] Add more template tag plugins (#3) --- .github/workflows/ci.yaml | 3 + package-lock.json | 156 +- package.json | 2 +- plugins/exporter-curl/package.json | 2 +- plugins/filter-jsonpath/package-lock.json | 175 -- plugins/filter-jsonpath/package.json | 2 +- plugins/filter-xpath/package-lock.json | 145 -- plugins/filter-xpath/package.json | 2 +- plugins/importer-curl/package-lock.json | 1673 ---------------- plugins/importer-curl/package.json | 5 +- plugins/importer-insomnia/package-lock.json | 139 -- plugins/importer-insomnia/package.json | 2 +- plugins/importer-openapi/package-lock.json | 1001 ---------- plugins/importer-openapi/package.json | 5 +- plugins/importer-openapi/src/index.ts | 2 +- plugins/importer-postman/package-lock.json | 1619 --------------- plugins/importer-postman/package.json | 2 +- plugins/importer-yaak/package-lock.json | 534 ----- plugins/importer-yaak/package.json | 2 +- plugins/template-function-file/package.json | 9 + plugins/template-function-file/src/index.ts | 18 + plugins/template-function-hash/package.json | 9 + plugins/template-function-hash/src/index.ts | 24 + plugins/template-function-prompt/package.json | 9 + plugins/template-function-prompt/src/index.ts | 24 + .../template-function-request/package.json | 9 + .../template-function-request/src/index.ts | 45 + .../package-lock.json | 1730 ----------------- .../template-function-response/src/index.ts | 222 ++- 29 files changed, 411 insertions(+), 7159 deletions(-) delete mode 100644 plugins/filter-jsonpath/package-lock.json delete mode 100644 plugins/filter-xpath/package-lock.json delete mode 100644 plugins/importer-curl/package-lock.json delete mode 100644 plugins/importer-insomnia/package-lock.json delete mode 100644 plugins/importer-openapi/package-lock.json delete mode 100644 plugins/importer-postman/package-lock.json delete mode 100644 plugins/importer-yaak/package-lock.json create mode 100644 plugins/template-function-file/package.json create mode 100644 plugins/template-function-file/src/index.ts create mode 100755 plugins/template-function-hash/package.json create mode 100755 plugins/template-function-hash/src/index.ts create mode 100644 plugins/template-function-prompt/package.json create mode 100644 plugins/template-function-prompt/src/index.ts create mode 100755 plugins/template-function-request/package.json create mode 100755 plugins/template-function-request/src/index.ts delete mode 100644 plugins/template-function-response/package-lock.json diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6c11c26c0..bbc346844 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,6 +12,9 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 + - name: Install @yaakapp/cli + run: npm install -g @yaakapp/cli + - name: Install Dependencies run: npm install diff --git a/package-lock.json b/package-lock.json index bb2fd18f3..b488ea6cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.2.9" + "@yaakapp/api": "^0.2.15" }, "devDependencies": { "@types/node": "^22.7.4", @@ -885,6 +885,33 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/openapi-to-postmanv2": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@types/openapi-to-postmanv2/-/openapi-to-postmanv2-3.2.4.tgz", + "integrity": "sha512-5SMU3TY2gmQRs6Ri7WRlI7tF2QEK0K4GfL50ghAPOUv4NkxhG37Aq2qystytm9fcmUgHDfyrkwZyprRgp85mxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/postman-collection": "*" + } + }, + "node_modules/@types/postman-collection": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/postman-collection/-/postman-collection-3.5.10.tgz", + "integrity": "sha512-l8xAUZNW9MzKWyeWuPgQlnyvpX8beeLqXYZTixr55Figae8/0gFb5l5GcU1y+3yeDmbXdY57cGxdvu+4OGbMdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/shell-quote": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@types/shell-quote/-/shell-quote-1.7.5.tgz", + "integrity": "sha512-+UE8GAGRPbJVQDdxi16dgadcBfQ+KG2vgZhV1+3A1XmHbmwcdwhCUwIdy+d3pAGrbvgRoVSjeI9vOWyq376Yzw==", + "dev": true, + "license": "MIT" + }, "node_modules/@vitest/expect": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.4.tgz", @@ -976,13 +1003,61 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.9.tgz", - "integrity": "sha512-0l6kfLWDqf0eKFeGE/8xKtqDNH/30YUPL9QW4ZvIB+daVqfhrJ/5V0JMR+g1atU+EXBe2E/WViaQmcK5lgBOng==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.15.tgz", + "integrity": "sha512-SW5S3Ca00Qo8Z/IhzCWrSQU0CZHHHCZwuDZtJkjTbfVL5Lv0DAaZsORNEIaeHyuqeQU9xRoi+Wr/WHoA3bG6+A==", "dependencies": { "@types/node": "^22.5.4" } }, + "node_modules/@yaakapp/exporter-curl": { + "resolved": "plugins/exporter-curl", + "link": true + }, + "node_modules/@yaakapp/filter-jsonpath": { + "resolved": "plugins/filter-jsonpath", + "link": true + }, + "node_modules/@yaakapp/filter-xpath": { + "resolved": "plugins/filter-xpath", + "link": true + }, + "node_modules/@yaakapp/importer-curl": { + "resolved": "plugins/importer-curl", + "link": true + }, + "node_modules/@yaakapp/importer-insomnia": { + "resolved": "plugins/importer-insomnia", + "link": true + }, + "node_modules/@yaakapp/importer-openapi": { + "resolved": "plugins/importer-openapi", + "link": true + }, + "node_modules/@yaakapp/importer-postman": { + "resolved": "plugins/importer-postman", + "link": true + }, + "node_modules/@yaakapp/importer-yaak": { + "resolved": "plugins/importer-yaak", + "link": true + }, + "node_modules/@yaakapp/template-function-file": { + "resolved": "plugins/template-function-file", + "link": true + }, + "node_modules/@yaakapp/template-function-hash": { + "resolved": "plugins/template-function-hash", + "link": true + }, + "node_modules/@yaakapp/template-function-prompt": { + "resolved": "plugins/template-function-prompt", + "link": true + }, + "node_modules/@yaakapp/template-function-request": { + "resolved": "plugins/template-function-request", + "link": true + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -2237,10 +2312,6 @@ "dev": true, "license": "MIT" }, - "node_modules/exporter-curl": { - "resolved": "plugins/exporter-curl", - "link": true - }, "node_modules/extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", @@ -2508,14 +2579,6 @@ "node": ">=8" } }, - "node_modules/filter-jsonpath": { - "resolved": "plugins/filter-jsonpath", - "link": true - }, - "node_modules/filter-xpath": { - "resolved": "plugins/filter-xpath", - "link": true - }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -3069,26 +3132,6 @@ "node": ">= 4" } }, - "node_modules/importer-curl": { - "resolved": "plugins/importer-curl", - "link": true - }, - "node_modules/importer-insomnia": { - "resolved": "plugins/importer-insomnia", - "link": true - }, - "node_modules/importer-openapi": { - "resolved": "plugins/importer-openapi", - "link": true - }, - "node_modules/importer-postman": { - "resolved": "plugins/importer-postman", - "link": true - }, - "node_modules/importer-yaak": { - "resolved": "plugins/importer-yaak", - "link": true - }, "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -5771,10 +5814,6 @@ "array-includes": "^3.0.3" } }, - "node_modules/template-function-request": { - "resolved": "plugins/template-function-request", - "link": true - }, "node_modules/template-function-response": { "resolved": "plugins/template-function-response", "link": true @@ -6604,9 +6643,11 @@ } }, "plugins/exporter-curl": { + "name": "@yaakapp/exporter-curl", "version": "0.0.1" }, "plugins/filter-jsonpath": { + "name": "@yaakapp/filter-jsonpath", "version": "0.0.1", "dependencies": { "jsonpath-plus": "^9.0.0" @@ -6616,6 +6657,7 @@ } }, "plugins/filter-xpath": { + "name": "@yaakapp/filter-xpath", "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", @@ -6623,40 +6665,56 @@ } }, "plugins/importer-curl": { + "name": "@yaakapp/importer-curl", "version": "0.0.1", "dependencies": { "shell-quote": "^1.8.1" + }, + "devDependencies": { + "@types/shell-quote": "^1.7.5" } }, "plugins/importer-insomnia": { + "name": "@yaakapp/importer-insomnia", "version": "0.0.1", "dependencies": { "yaml": "^2.4.2" } }, "plugins/importer-openapi": { + "name": "@yaakapp/importer-openapi", "version": "0.0.1", "dependencies": { "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" + }, + "devDependencies": { + "@types/openapi-to-postmanv2": "^3.2.4" } }, "plugins/importer-postman": { + "name": "@yaakapp/importer-postman", "version": "0.0.1" }, "plugins/importer-yaak": { + "name": "@yaakapp/importer-yaak", + "version": "0.0.1" + }, + "plugins/template-function-file": { + "name": "@yaakapp/template-function-file", + "version": "0.0.1" + }, + "plugins/template-function-hash": { + "name": "@yaakapp/template-function-hash", + "version": "0.0.1" + }, + "plugins/template-function-prompt": { + "name": "@yaakapp/template-function-prompt", "version": "0.0.1" }, "plugins/template-function-request": { - "version": "0.0.1", - "dependencies": { - "@xmldom/xmldom": "^0.8.10", - "jsonpath-plus": "^9.0.0", - "xpath": "^0.0.34" - }, - "devDependencies": { - "@types/jsonpath": "^0.2.4" - } + "name": "@yaakapp/template-function-request", + "version": "0.0.1" }, "plugins/template-function-response": { "version": "0.0.1", diff --git a/package.json b/package.json index 500caa6cc..1633ca27a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.2.9" + "@yaakapp/api": "^0.2.15" } } diff --git a/plugins/exporter-curl/package.json b/plugins/exporter-curl/package.json index 60ae346b0..283c3c5db 100644 --- a/plugins/exporter-curl/package.json +++ b/plugins/exporter-curl/package.json @@ -1,5 +1,5 @@ { - "name": "exporter-curl", + "name": "@yaakapp/exporter-curl", "private": true, "version": "0.0.1", "scripts": { diff --git a/plugins/filter-jsonpath/package-lock.json b/plugins/filter-jsonpath/package-lock.json deleted file mode 100644 index 876f14f4c..000000000 --- a/plugins/filter-jsonpath/package-lock.json +++ /dev/null @@ -1,175 +0,0 @@ -{ - "name": "filter-jsonpath", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "filter-jsonpath", - "version": "0.0.1", - "dependencies": { - "@yaakapp/api": "^0.2.9", - "jsonpath-plus": "^9.0.0" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "@yaakapp/cli": "^0.0.42", - "typescript": "^5.5.2" - } - }, - "node_modules/@jsep-plugin/assignment": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.2.1.tgz", - "integrity": "sha512-gaHqbubTi29aZpVbBlECRpmdia+L5/lh2BwtIJTmtxdbecEyyX/ejAOg7eQDGNvGOUmPY7Z2Yxdy9ioyH/VJeA==", - "engines": { - "node": ">= 10.16.0" - }, - "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" - } - }, - "node_modules/@jsep-plugin/regex": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", - "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", - "engines": { - "node": ">= 10.16.0" - }, - "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" - } - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@yaakapp/api": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.8.tgz", - "integrity": "sha512-m+6xHIH/X8uTP65oeaSGmz90UOhl7sW5E2rNKix5MEKSFg0BzBupXMjBIT6EXtrxcCvUdOPtSP3ARriWsiZixQ==", - "dependencies": { - "@types/node": "^22.5.4" - } - }, - "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/@yaakapp/cli": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", - "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "yaakcli": "bin/cli.js" - }, - "optionalDependencies": { - "@yaakapp/cli-darwin-arm64": "0.0.42", - "@yaakapp/cli-darwin-x64": "0.0.42", - "@yaakapp/cli-linux-x64": "0.0.42", - "@yaakapp/cli-win32-x64": "0.0.42" - } - }, - "node_modules/@yaakapp/cli-darwin-arm64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", - "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-darwin-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", - "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-linux-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", - "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yaakapp/cli-win32-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", - "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/jsep": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.9.tgz", - "integrity": "sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==", - "engines": { - "node": ">= 10.16.0" - } - }, - "node_modules/jsonpath-plus": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-9.0.0.tgz", - "integrity": "sha512-bqE77VIDStrOTV/czspZhTn+o27Xx9ZJRGVkdVShEtPoqsIx5yALv3lWVU6y+PqYvWPJNWE7ORCQheQkEe0DDA==", - "dependencies": { - "@jsep-plugin/assignment": "^1.2.1", - "@jsep-plugin/regex": "^1.0.3", - "jsep": "^1.3.8" - }, - "bin": { - "jsonpath": "bin/jsonpath-cli.js", - "jsonpath-plus": "bin/jsonpath-cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - } - } -} diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index 80115b31d..4d1a1c5a9 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -1,5 +1,5 @@ { - "name": "filter-jsonpath", + "name": "@yaakapp/filter-jsonpath", "private": true, "version": "0.0.1", "scripts": { diff --git a/plugins/filter-xpath/package-lock.json b/plugins/filter-xpath/package-lock.json deleted file mode 100644 index 949d11d4b..000000000 --- a/plugins/filter-xpath/package-lock.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "name": "filter-xpath", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "filter-xpath", - "version": "0.0.1", - "dependencies": { - "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.2.9", - "xpath": "^0.0.34" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "@yaakapp/cli": "^0.0.42", - "typescript": "^5.5.2" - } - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@yaakapp/api": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.8.tgz", - "integrity": "sha512-m+6xHIH/X8uTP65oeaSGmz90UOhl7sW5E2rNKix5MEKSFg0BzBupXMjBIT6EXtrxcCvUdOPtSP3ARriWsiZixQ==", - "dependencies": { - "@types/node": "^22.5.4" - } - }, - "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/@yaakapp/cli": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", - "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "yaakcli": "bin/cli.js" - }, - "optionalDependencies": { - "@yaakapp/cli-darwin-arm64": "0.0.42", - "@yaakapp/cli-darwin-x64": "0.0.42", - "@yaakapp/cli-linux-x64": "0.0.42", - "@yaakapp/cli-win32-x64": "0.0.42" - } - }, - "node_modules/@yaakapp/cli-darwin-arm64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", - "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-darwin-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", - "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-linux-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", - "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yaakapp/cli-win32-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", - "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/xpath": { - "version": "0.0.34", - "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", - "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==", - "engines": { - "node": ">=0.6.0" - } - } - } -} diff --git a/plugins/filter-xpath/package.json b/plugins/filter-xpath/package.json index 89b9e26d6..4ca5c711c 100644 --- a/plugins/filter-xpath/package.json +++ b/plugins/filter-xpath/package.json @@ -1,5 +1,5 @@ { - "name": "filter-xpath", + "name": "@yaakapp/filter-xpath", "private": true, "version": "0.0.1", "scripts": { diff --git a/plugins/importer-curl/package-lock.json b/plugins/importer-curl/package-lock.json deleted file mode 100644 index a096dadea..000000000 --- a/plugins/importer-curl/package-lock.json +++ /dev/null @@ -1,1673 +0,0 @@ -{ - "name": "importer-curl", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "importer-curl", - "version": "0.0.1", - "dependencies": { - "@yaakapp/api": "^0.2.9", - "shell-quote": "^1.8.1" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "@types/shell-quote": "^1.7.5", - "@yaakapp/cli": "^0.0.42", - "typescript": "^5.5.2", - "vitest": "^1.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/shell-quote": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/@types/shell-quote/-/shell-quote-1.7.5.tgz", - "integrity": "sha512-+UE8GAGRPbJVQDdxi16dgadcBfQ+KG2vgZhV1+3A1XmHbmwcdwhCUwIdy+d3pAGrbvgRoVSjeI9vOWyq376Yzw==", - "dev": true - }, - "node_modules/@vitest/expect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", - "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", - "dev": true, - "dependencies": { - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "chai": "^4.3.10" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", - "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", - "dev": true, - "dependencies": { - "@vitest/utils": "1.6.0", - "p-limit": "^5.0.0", - "pathe": "^1.1.1" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", - "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", - "dev": true, - "dependencies": { - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "pretty-format": "^29.7.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", - "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", - "dev": true, - "dependencies": { - "tinyspy": "^2.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", - "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", - "dev": true, - "dependencies": { - "diff-sequences": "^29.6.3", - "estree-walker": "^3.0.3", - "loupe": "^2.3.7", - "pretty-format": "^29.7.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@yaakapp/api": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.8.tgz", - "integrity": "sha512-m+6xHIH/X8uTP65oeaSGmz90UOhl7sW5E2rNKix5MEKSFg0BzBupXMjBIT6EXtrxcCvUdOPtSP3ARriWsiZixQ==", - "dependencies": { - "@types/node": "^22.5.4" - } - }, - "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/@yaakapp/cli": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", - "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "yaakcli": "bin/cli.js" - }, - "optionalDependencies": { - "@yaakapp/cli-darwin-arm64": "0.0.42", - "@yaakapp/cli-darwin-x64": "0.0.42", - "@yaakapp/cli-linux-x64": "0.0.42", - "@yaakapp/cli-win32-x64": "0.0.42" - } - }, - "node_modules/@yaakapp/cli-darwin-arm64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", - "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-darwin-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", - "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-linux-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", - "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yaakapp/cli-win32-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", - "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-styles": { - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/confbox": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", - "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", - "dev": true - }, - "node_modules/local-pkg": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", - "dev": true, - "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mlly": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.0.tgz", - "integrity": "sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==", - "dev": true, - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.1.0", - "ufo": "^1.5.3" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/pkg-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz", - "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==", - "dev": true, - "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.6.1", - "pathe": "^1.1.2" - } - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true - }, - "node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true - }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", - "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", - "dev": true, - "dependencies": { - "js-tokens": "^9.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/tinybench": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", - "dev": true - }, - "node_modules/tinypool": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", - "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", - "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", - "dev": true - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/vite": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", - "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", - "dev": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", - "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", - "dev": true, - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vitest": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", - "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", - "dev": true, - "dependencies": { - "@vitest/expect": "1.6.0", - "@vitest/runner": "1.6.0", - "@vitest/snapshot": "1.6.0", - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "acorn-walk": "^8.3.2", - "chai": "^4.3.10", - "debug": "^4.3.4", - "execa": "^8.0.1", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.5.0", - "strip-literal": "^2.0.0", - "tinybench": "^2.5.1", - "tinypool": "^0.8.3", - "vite": "^5.0.0", - "vite-node": "1.6.0", - "why-is-node-running": "^2.2.2" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.6.0", - "@vitest/ui": "1.6.0", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/why-is-node-running": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", - "dev": true, - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/plugins/importer-curl/package.json b/plugins/importer-curl/package.json index 154ebf563..53ef8d3bd 100644 --- a/plugins/importer-curl/package.json +++ b/plugins/importer-curl/package.json @@ -1,5 +1,5 @@ { - "name": "importer-curl", + "name": "@yaakapp/importer-curl", "private": true, "version": "0.0.1", "scripts": { @@ -8,5 +8,8 @@ }, "dependencies": { "shell-quote": "^1.8.1" + }, + "devDependencies": { + "@types/shell-quote": "^1.7.5" } } diff --git a/plugins/importer-insomnia/package-lock.json b/plugins/importer-insomnia/package-lock.json deleted file mode 100644 index ef7c77847..000000000 --- a/plugins/importer-insomnia/package-lock.json +++ /dev/null @@ -1,139 +0,0 @@ -{ - "name": "importer-insomnia", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "importer-insomnia", - "version": "0.0.1", - "dependencies": { - "@yaakapp/api": "^0.2.9", - "yaml": "^2.4.2" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "@yaakapp/cli": "^0.0.42", - "typescript": "^5.5.2" - } - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@yaakapp/api": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.8.tgz", - "integrity": "sha512-m+6xHIH/X8uTP65oeaSGmz90UOhl7sW5E2rNKix5MEKSFg0BzBupXMjBIT6EXtrxcCvUdOPtSP3ARriWsiZixQ==", - "dependencies": { - "@types/node": "^22.5.4" - } - }, - "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/@yaakapp/cli": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", - "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "yaakcli": "bin/cli.js" - }, - "optionalDependencies": { - "@yaakapp/cli-darwin-arm64": "0.0.42", - "@yaakapp/cli-darwin-x64": "0.0.42", - "@yaakapp/cli-linux-x64": "0.0.42", - "@yaakapp/cli-win32-x64": "0.0.42" - } - }, - "node_modules/@yaakapp/cli-darwin-arm64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", - "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-darwin-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", - "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-linux-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", - "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yaakapp/cli-win32-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", - "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/yaml": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", - "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - } - } -} diff --git a/plugins/importer-insomnia/package.json b/plugins/importer-insomnia/package.json index 18b80f09a..d0764c8c6 100644 --- a/plugins/importer-insomnia/package.json +++ b/plugins/importer-insomnia/package.json @@ -1,5 +1,5 @@ { - "name": "importer-insomnia", + "name": "@yaakapp/importer-insomnia", "private": true, "version": "0.0.1", "scripts": { diff --git a/plugins/importer-openapi/package-lock.json b/plugins/importer-openapi/package-lock.json deleted file mode 100644 index c2a8093be..000000000 --- a/plugins/importer-openapi/package-lock.json +++ /dev/null @@ -1,1001 +0,0 @@ -{ - "name": "importer-openapi", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "importer-openapi", - "version": "0.0.1", - "dependencies": { - "@yaakapp/api": "^0.2.9", - "openapi-to-postmanv2": "^4.23.1", - "yaml": "^2.4.2" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "@types/openapi-to-postmanv2": "^3.2.4", - "@yaakapp/cli": "^0.0.42", - "typescript": "^5.5.2" - } - }, - "node_modules/@exodus/schemasafe": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", - "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==" - }, - "node_modules/@faker-js/faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-R11tGE6yIFwqpaIqcfkcg7AICXzFg14+5h5v0TfF/9+RMDL6jhzCy/pxHVOfbALGdtVYdt6JdR21tuxEgl34dw==" - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/openapi-to-postmanv2": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@types/openapi-to-postmanv2/-/openapi-to-postmanv2-3.2.4.tgz", - "integrity": "sha512-5SMU3TY2gmQRs6Ri7WRlI7tF2QEK0K4GfL50ghAPOUv4NkxhG37Aq2qystytm9fcmUgHDfyrkwZyprRgp85mxg==", - "dev": true, - "dependencies": { - "@types/postman-collection": "*" - } - }, - "node_modules/@types/postman-collection": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/postman-collection/-/postman-collection-3.5.10.tgz", - "integrity": "sha512-l8xAUZNW9MzKWyeWuPgQlnyvpX8beeLqXYZTixr55Figae8/0gFb5l5GcU1y+3yeDmbXdY57cGxdvu+4OGbMdg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@yaakapp/api": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.8.tgz", - "integrity": "sha512-m+6xHIH/X8uTP65oeaSGmz90UOhl7sW5E2rNKix5MEKSFg0BzBupXMjBIT6EXtrxcCvUdOPtSP3ARriWsiZixQ==", - "dependencies": { - "@types/node": "^22.5.4" - } - }, - "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/@yaakapp/cli": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", - "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "yaakcli": "bin/cli.js" - }, - "optionalDependencies": { - "@yaakapp/cli-darwin-arm64": "0.0.42", - "@yaakapp/cli-darwin-x64": "0.0.42", - "@yaakapp/cli-linux-x64": "0.0.42", - "@yaakapp/cli-win32-x64": "0.0.42" - } - }, - "node_modules/@yaakapp/cli-darwin-arm64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", - "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-darwin-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", - "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-linux-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", - "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yaakapp/cli-win32-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", - "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "peerDependencies": { - "ajv": "^8.5.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "node_modules/call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" - }, - "node_modules/charset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/charset/-/charset-1.0.1.tgz", - "integrity": "sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/compute-gcd": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", - "integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==", - "dependencies": { - "validate.io-array": "^1.0.3", - "validate.io-function": "^1.0.2", - "validate.io-integer-array": "^1.0.0" - } - }, - "node_modules/compute-lcm": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz", - "integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==", - "dependencies": { - "compute-gcd": "^1.2.1", - "validate.io-array": "^1.0.3", - "validate.io-function": "^1.0.2", - "validate.io-integer-array": "^1.0.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==" - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", - "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", - "dependencies": { - "lodash": "^4.17.15" - } - }, - "node_modules/http-reasons": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/http-reasons/-/http-reasons-0.1.0.tgz", - "integrity": "sha512-P6kYh0lKZ+y29T2Gqz+RlC9WBLhKe8kDmcJ+A+611jFfxdPsbMRQ5aNmFRM3lENqFkK+HTTL+tlQviAiv0AbLQ==" - }, - "node_modules/http2-client": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", - "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==" - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-compare": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", - "integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==", - "dependencies": { - "lodash": "^4.17.4" - } - }, - "node_modules/json-schema-merge-allof": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", - "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", - "dependencies": { - "compute-lcm": "^1.1.2", - "json-schema-compare": "^0.2.2", - "lodash": "^4.17.20" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/liquid-json": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/liquid-json/-/liquid-json-0.3.1.tgz", - "integrity": "sha512-wUayTU8MS827Dam6MxgD72Ui+KOSF+u/eIqpatOtjnvgJ0+mnDq33uC2M7J0tPK+upe/DpUAuK4JUU89iBoNKQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-format": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mime-format/-/mime-format-2.0.1.tgz", - "integrity": "sha512-XxU3ngPbEnrYnNbIX+lYSaYg0M01v6p2ntd2YaFksTu0vayaw5OJvbdRyWs07EYRlLED5qadUZ+xo+XhOvFhwg==", - "dependencies": { - "charset": "^1.0.0" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch-h2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz", - "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==", - "dependencies": { - "http2-client": "^1.2.5" - }, - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/node-readfiles": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", - "integrity": "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==", - "dependencies": { - "es6-promise": "^3.2.1" - } - }, - "node_modules/oas-kit-common": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", - "integrity": "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==", - "dependencies": { - "fast-safe-stringify": "^2.0.7" - } - }, - "node_modules/oas-linter": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/oas-linter/-/oas-linter-3.2.2.tgz", - "integrity": "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==", - "dependencies": { - "@exodus/schemasafe": "^1.0.0-rc.2", - "should": "^13.2.1", - "yaml": "^1.10.0" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/oas-linter/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/oas-resolver": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", - "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", - "dependencies": { - "node-fetch-h2": "^2.3.0", - "oas-kit-common": "^1.0.8", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - }, - "bin": { - "resolve": "resolve.js" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/oas-resolver-browser": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/oas-resolver-browser/-/oas-resolver-browser-2.5.6.tgz", - "integrity": "sha512-Jw5elT/kwUJrnGaVuRWe1D7hmnYWB8rfDDjBnpQ+RYY/dzAewGXeTexXzt4fGEo6PUE4eqKqPWF79MZxxvMppA==", - "dependencies": { - "node-fetch-h2": "^2.3.0", - "oas-kit-common": "^1.0.8", - "path-browserify": "^1.0.1", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - }, - "bin": { - "resolve": "resolve.js" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/oas-resolver-browser/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/oas-resolver/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/oas-schema-walker": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", - "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==", - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/oas-validator": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", - "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", - "dependencies": { - "call-me-maybe": "^1.0.1", - "oas-kit-common": "^1.0.8", - "oas-linter": "^3.2.2", - "oas-resolver": "^2.5.6", - "oas-schema-walker": "^1.1.5", - "reftools": "^1.1.9", - "should": "^13.2.1", - "yaml": "^1.10.0" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/oas-validator/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/openapi-to-postmanv2": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/openapi-to-postmanv2/-/openapi-to-postmanv2-4.23.1.tgz", - "integrity": "sha512-vNGU95euiXriNw7sVJ82uZyCyV8rXxSkc5o8bcDQh2IonO6cwzVUbrfYPnnj6A18YTGHSWHhQpUy0otxDHFoCw==", - "dependencies": { - "ajv": "8.11.0", - "ajv-draft-04": "1.0.0", - "ajv-formats": "2.1.1", - "async": "3.2.4", - "commander": "2.20.3", - "graphlib": "2.1.8", - "js-yaml": "4.1.0", - "json-schema-merge-allof": "0.8.1", - "lodash": "4.17.21", - "oas-resolver-browser": "2.5.6", - "object-hash": "3.0.0", - "path-browserify": "1.0.1", - "postman-collection": "^4.4.0", - "swagger2openapi": "7.0.8", - "traverse": "0.6.6", - "yaml": "1.10.2" - }, - "bin": { - "openapi2postmanv2": "bin/openapi2postmanv2.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/openapi-to-postmanv2/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" - }, - "node_modules/postman-collection": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.4.0.tgz", - "integrity": "sha512-2BGDFcUwlK08CqZFUlIC8kwRJueVzPjZnnokWPtJCd9f2J06HBQpGL7t2P1Ud1NEsK9NHq9wdipUhWLOPj5s/Q==", - "dependencies": { - "@faker-js/faker": "5.5.3", - "file-type": "3.9.0", - "http-reasons": "0.1.0", - "iconv-lite": "0.6.3", - "liquid-json": "0.3.1", - "lodash": "4.17.21", - "mime-format": "2.0.1", - "mime-types": "2.1.35", - "postman-url-encoder": "3.0.5", - "semver": "7.5.4", - "uuid": "8.3.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postman-url-encoder": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/postman-url-encoder/-/postman-url-encoder-3.0.5.tgz", - "integrity": "sha512-jOrdVvzUXBC7C+9gkIkpDJ3HIxOHTIqjpQ4C1EMt1ZGeMvSEpbFCKq23DEfgsj46vMnDgyQf+1ZLp2Wm+bKSsA==", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/reftools": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", - "integrity": "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==", - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/should": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", - "dependencies": { - "should-equal": "^2.0.0", - "should-format": "^3.0.3", - "should-type": "^1.4.0", - "should-type-adaptors": "^1.0.1", - "should-util": "^1.0.0" - } - }, - "node_modules/should-equal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", - "dependencies": { - "should-type": "^1.4.0" - } - }, - "node_modules/should-format": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", - "dependencies": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" - } - }, - "node_modules/should-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==" - }, - "node_modules/should-type-adaptors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", - "dependencies": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" - } - }, - "node_modules/should-util": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", - "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==" - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/swagger2openapi": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/swagger2openapi/-/swagger2openapi-7.0.8.tgz", - "integrity": "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==", - "dependencies": { - "call-me-maybe": "^1.0.1", - "node-fetch": "^2.6.1", - "node-fetch-h2": "^2.3.0", - "node-readfiles": "^0.2.0", - "oas-kit-common": "^1.0.8", - "oas-resolver": "^2.5.6", - "oas-schema-walker": "^1.1.5", - "oas-validator": "^5.0.8", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - }, - "bin": { - "boast": "boast.js", - "oas-validate": "oas-validate.js", - "swagger2openapi": "swagger2openapi.js" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/swagger2openapi/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" - }, - "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/validate.io-array": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz", - "integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==" - }, - "node_modules/validate.io-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz", - "integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==" - }, - "node_modules/validate.io-integer": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz", - "integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==", - "dependencies": { - "validate.io-number": "^1.0.3" - } - }, - "node_modules/validate.io-integer-array": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz", - "integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==", - "dependencies": { - "validate.io-array": "^1.0.3", - "validate.io-integer": "^1.0.4" - } - }, - "node_modules/validate.io-number": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz", - "integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg==" - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - } - } -} diff --git a/plugins/importer-openapi/package.json b/plugins/importer-openapi/package.json index 575b0433f..9ea28dd10 100644 --- a/plugins/importer-openapi/package.json +++ b/plugins/importer-openapi/package.json @@ -1,5 +1,5 @@ { - "name": "importer-openapi", + "name": "@yaakapp/importer-openapi", "private": true, "version": "0.0.1", "scripts": { @@ -9,5 +9,8 @@ "dependencies": { "openapi-to-postmanv2": "^4.23.1", "yaml": "^2.4.2" + }, + "devDependencies": { + "@types/openapi-to-postmanv2": "^3.2.4" } } diff --git a/plugins/importer-openapi/src/index.ts b/plugins/importer-openapi/src/index.ts index 6ff684bf3..87b8a1178 100644 --- a/plugins/importer-openapi/src/index.ts +++ b/plugins/importer-openapi/src/index.ts @@ -1,7 +1,7 @@ import { Context } from '@yaakapp/api'; import { convert } from 'openapi-to-postmanv2'; import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman/src/index'; -import { Folder, HttpRequest, Workspace, Environment } from '../../../types/models'; +import { Folder, HttpRequest, Workspace, Environment } from '@yaakapp/api'; type AtLeast = Partial & Pick; diff --git a/plugins/importer-postman/package-lock.json b/plugins/importer-postman/package-lock.json deleted file mode 100644 index 94111ee6d..000000000 --- a/plugins/importer-postman/package-lock.json +++ /dev/null @@ -1,1619 +0,0 @@ -{ - "name": "importer-postman", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "importer-postman", - "version": "0.0.1", - "dependencies": { - "@yaakapp/api": "^0.2.9" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "@yaakapp/cli": "^0.0.42", - "esbuild": "^0.21.5", - "typescript": "^5.5.2", - "vitest": "^1.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", - "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", - "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", - "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", - "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", - "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", - "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", - "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", - "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", - "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", - "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", - "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", - "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", - "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@vitest/expect": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.4.0.tgz", - "integrity": "sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==", - "dev": true, - "dependencies": { - "@vitest/spy": "1.4.0", - "@vitest/utils": "1.4.0", - "chai": "^4.3.10" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.4.0.tgz", - "integrity": "sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==", - "dev": true, - "dependencies": { - "@vitest/utils": "1.4.0", - "p-limit": "^5.0.0", - "pathe": "^1.1.1" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.4.0.tgz", - "integrity": "sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==", - "dev": true, - "dependencies": { - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "pretty-format": "^29.7.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz", - "integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==", - "dev": true, - "dependencies": { - "tinyspy": "^2.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz", - "integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==", - "dev": true, - "dependencies": { - "diff-sequences": "^29.6.3", - "estree-walker": "^3.0.3", - "loupe": "^2.3.7", - "pretty-format": "^29.7.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@yaakapp/api": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", - "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", - "dependencies": { - "@types/node": "^22.5.4" - } - }, - "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/@yaakapp/cli": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", - "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "yaakcli": "bin/cli.js" - }, - "optionalDependencies": { - "@yaakapp/cli-darwin-arm64": "0.0.42", - "@yaakapp/cli-darwin-x64": "0.0.42", - "@yaakapp/cli-linux-x64": "0.0.42", - "@yaakapp/cli-win32-x64": "0.0.42" - } - }, - "node_modules/@yaakapp/cli-darwin-arm64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", - "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-darwin-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", - "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-linux-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", - "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yaakapp/cli-win32-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", - "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-styles": { - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", - "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", - "dev": true - }, - "node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true - }, - "node_modules/local-pkg": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", - "dev": true, - "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mlly": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", - "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", - "dev": true, - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.0.3", - "ufo": "^1.3.2" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/pkg-types": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", - "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", - "dev": true, - "dependencies": { - "jsonc-parser": "^3.2.0", - "mlly": "^1.2.0", - "pathe": "^1.1.0" - } - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/rollup": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", - "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.13.0", - "@rollup/rollup-android-arm64": "4.13.0", - "@rollup/rollup-darwin-arm64": "4.13.0", - "@rollup/rollup-darwin-x64": "4.13.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", - "@rollup/rollup-linux-arm64-gnu": "4.13.0", - "@rollup/rollup-linux-arm64-musl": "4.13.0", - "@rollup/rollup-linux-riscv64-gnu": "4.13.0", - "@rollup/rollup-linux-x64-gnu": "4.13.0", - "@rollup/rollup-linux-x64-musl": "4.13.0", - "@rollup/rollup-win32-arm64-msvc": "4.13.0", - "@rollup/rollup-win32-ia32-msvc": "4.13.0", - "@rollup/rollup-win32-x64-msvc": "4.13.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true - }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz", - "integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==", - "dev": true, - "dependencies": { - "js-tokens": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/tinybench": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", - "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", - "dev": true - }, - "node_modules/tinypool": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz", - "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.2.tgz", - "integrity": "sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==", - "dev": true - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/vite": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", - "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", - "dev": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.4.0.tgz", - "integrity": "sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==", - "dev": true, - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vitest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.4.0.tgz", - "integrity": "sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==", - "dev": true, - "dependencies": { - "@vitest/expect": "1.4.0", - "@vitest/runner": "1.4.0", - "@vitest/snapshot": "1.4.0", - "@vitest/spy": "1.4.0", - "@vitest/utils": "1.4.0", - "acorn-walk": "^8.3.2", - "chai": "^4.3.10", - "debug": "^4.3.4", - "execa": "^8.0.1", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.5.0", - "strip-literal": "^2.0.0", - "tinybench": "^2.5.1", - "tinypool": "^0.8.2", - "vite": "^5.0.0", - "vite-node": "1.4.0", - "why-is-node-running": "^2.2.2" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.4.0", - "@vitest/ui": "1.4.0", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/why-is-node-running": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", - "dev": true, - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/plugins/importer-postman/package.json b/plugins/importer-postman/package.json index a2b5d02a5..10f0a1a12 100644 --- a/plugins/importer-postman/package.json +++ b/plugins/importer-postman/package.json @@ -1,5 +1,5 @@ { - "name": "importer-postman", + "name": "@yaakapp/importer-postman", "private": true, "version": "0.0.1", "main": "./build/index.js", diff --git a/plugins/importer-yaak/package-lock.json b/plugins/importer-yaak/package-lock.json deleted file mode 100644 index a9c9c56df..000000000 --- a/plugins/importer-yaak/package-lock.json +++ /dev/null @@ -1,534 +0,0 @@ -{ - "name": "importer-yaak", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "importer-yaak", - "version": "0.0.1", - "dependencies": { - "@yaakapp/api": "^0.2.9" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "@yaakapp/cli": "^0.0.42", - "esbuild": "^0.21.5", - "typescript": "^5.5.2" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@yaakapp/api": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", - "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", - "dependencies": { - "@types/node": "^22.5.4" - } - }, - "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/@yaakapp/cli": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", - "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "yaakcli": "bin/cli.js" - }, - "optionalDependencies": { - "@yaakapp/cli-darwin-arm64": "0.0.42", - "@yaakapp/cli-darwin-x64": "0.0.42", - "@yaakapp/cli-linux-x64": "0.0.42", - "@yaakapp/cli-win32-x64": "0.0.42" - } - }, - "node_modules/@yaakapp/cli-darwin-arm64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", - "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-darwin-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", - "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-linux-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", - "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yaakapp/cli-win32-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", - "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - } - } -} diff --git a/plugins/importer-yaak/package.json b/plugins/importer-yaak/package.json index e44fbae56..f22d8beee 100644 --- a/plugins/importer-yaak/package.json +++ b/plugins/importer-yaak/package.json @@ -1,5 +1,5 @@ { - "name": "importer-yaak", + "name": "@yaakapp/importer-yaak", "private": true, "version": "0.0.1", "scripts": { diff --git a/plugins/template-function-file/package.json b/plugins/template-function-file/package.json new file mode 100644 index 000000000..59aea7ab3 --- /dev/null +++ b/plugins/template-function-file/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/template-function-file", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/plugins/template-function-file/src/index.ts b/plugins/template-function-file/src/index.ts new file mode 100644 index 000000000..472c1a0d9 --- /dev/null +++ b/plugins/template-function-file/src/index.ts @@ -0,0 +1,18 @@ +import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; +import fs from 'node:fs'; + +export const plugin: PluginDefinition = { + templateFunctions: [{ + name: 'fs.readFile', + args: [{ title: 'Select File', type: 'file', name: 'path', label: 'File' }], + async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { + if (!args.values.path) return null; + + try { + return fs.promises.readFile(args.values.path, 'utf-8'); + } catch (err) { + return null; + } + }, + }], +}; diff --git a/plugins/template-function-hash/package.json b/plugins/template-function-hash/package.json new file mode 100755 index 000000000..5dbcb0d24 --- /dev/null +++ b/plugins/template-function-hash/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/template-function-hash", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/plugins/template-function-hash/src/index.ts b/plugins/template-function-hash/src/index.ts new file mode 100755 index 000000000..8520c0b78 --- /dev/null +++ b/plugins/template-function-hash/src/index.ts @@ -0,0 +1,24 @@ +import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; +import { createHash } from 'node:crypto'; + +const algorithms = ['md5', 'sha1', 'sha256', 'sha512']; + +export const plugin: PluginDefinition = { + templateFunctions: algorithms.map(algorithm => ({ + name: `hash.${algorithm}`, + args: [ + { + name: 'input', + label: 'Input', + placeholder: 'input text', + type: 'text', + }, + ], + async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { + if (!args.values.input) return ''; + return createHash(algorithm) + .update(args.values.input, 'utf-8') + .digest('hex'); + }, + })), +}; diff --git a/plugins/template-function-prompt/package.json b/plugins/template-function-prompt/package.json new file mode 100644 index 000000000..26a09dfdf --- /dev/null +++ b/plugins/template-function-prompt/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/template-function-prompt", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/plugins/template-function-prompt/src/index.ts b/plugins/template-function-prompt/src/index.ts new file mode 100644 index 000000000..4941253ff --- /dev/null +++ b/plugins/template-function-prompt/src/index.ts @@ -0,0 +1,24 @@ +import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; + +export const plugin: PluginDefinition = { + templateFunctions: [{ + name: 'prompt.text', + args: [ + { type: 'text', name: 'title', label: 'Title' }, + { type: 'text', name: 'label', label: 'Label', optional: true }, + { type: 'text', name: 'defaultValue', label: 'Default Value', optional: true }, + { type: 'text', name: 'placeholder', label: 'Placeholder', optional: true }, + ], + async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { + if (args.purpose !== 'send') return null; + + return await ctx.prompt.text({ + id: `prompt-${args.values.label}`, + label: args.values.label ?? '', + title: args.values.title ?? '', + defaultValue: args.values.defaultValue, + placeholder: args.values.placeholder, + }); + }, + }], +}; diff --git a/plugins/template-function-request/package.json b/plugins/template-function-request/package.json new file mode 100755 index 000000000..a3ebb038d --- /dev/null +++ b/plugins/template-function-request/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/template-function-request", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/plugins/template-function-request/src/index.ts b/plugins/template-function-request/src/index.ts new file mode 100755 index 000000000..0567d5871 --- /dev/null +++ b/plugins/template-function-request/src/index.ts @@ -0,0 +1,45 @@ +import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; + +export const plugin: PluginDefinition = { + templateFunctions: [ + { + name: 'request.body', + args: [{ + name: 'requestId', + label: 'Http Request', + type: 'http_request', + }], + async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { + const httpRequest = await ctx.httpRequest.getById({ id: args.values.requestId ?? 'n/a' }); + if (httpRequest == null) return null; + return String(await ctx.templates.render({ + data: httpRequest.body?.text ?? '', + purpose: args.purpose, + })); + }, + }, + { + name: 'request.header', + args: [ + { + name: 'requestId', + label: 'Http Request', + type: 'http_request', + }, + { + name: 'header', + label: 'Header Name', + type: 'text', + }], + async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { + const httpRequest = await ctx.httpRequest.getById({ id: args.values.requestId ?? 'n/a' }); + if (httpRequest == null) return null; + const header = httpRequest.headers.find(h => h.name.toLowerCase() === args.values.header?.toLowerCase()); + return String(await ctx.templates.render({ + data: header?.value ?? '', + purpose: args.purpose, + })); + }, + }, + ], +}; diff --git a/plugins/template-function-response/package-lock.json b/plugins/template-function-response/package-lock.json deleted file mode 100644 index add531606..000000000 --- a/plugins/template-function-response/package-lock.json +++ /dev/null @@ -1,1730 +0,0 @@ -{ - "name": "template-function-response", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "template-function-response", - "version": "0.0.1", - "dependencies": { - "@xmldom/xmldom": "^0.8.10", - "@yaakapp/api": "^0.2.9", - "jsonpath-plus": "^9.0.0", - "xpath": "^0.0.34" - }, - "devDependencies": { - "@types/jsonpath": "^0.2.4", - "@types/node": "^20.14.9", - "@yaakapp/cli": "^0.0.42", - "typescript": "^5.5.2", - "vitest": "^1.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jsep-plugin/assignment": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.2.1.tgz", - "integrity": "sha512-gaHqbubTi29aZpVbBlECRpmdia+L5/lh2BwtIJTmtxdbecEyyX/ejAOg7eQDGNvGOUmPY7Z2Yxdy9ioyH/VJeA==", - "engines": { - "node": ">= 10.16.0" - }, - "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" - } - }, - "node_modules/@jsep-plugin/regex": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", - "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", - "engines": { - "node": ">= 10.16.0" - }, - "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/jsonpath": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.4.tgz", - "integrity": "sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@vitest/expect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", - "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", - "dev": true, - "dependencies": { - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "chai": "^4.3.10" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", - "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", - "dev": true, - "dependencies": { - "@vitest/utils": "1.6.0", - "p-limit": "^5.0.0", - "pathe": "^1.1.1" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", - "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", - "dev": true, - "dependencies": { - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "pretty-format": "^29.7.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", - "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", - "dev": true, - "dependencies": { - "tinyspy": "^2.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", - "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", - "dev": true, - "dependencies": { - "diff-sequences": "^29.6.3", - "estree-walker": "^3.0.3", - "loupe": "^2.3.7", - "pretty-format": "^29.7.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@yaakapp/api": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.7.tgz", - "integrity": "sha512-vU9KtEwe5a+6VpDtV5+GSV+BpZETer/M9TtZ+oDZovvFMO0d55KqPfs7S6PuMru6e8Yxky8mO1TjL4Vsylh2Gg==", - "dependencies": { - "@types/node": "^22.5.4" - } - }, - "node_modules/@yaakapp/api/node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@yaakapp/api/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/@yaakapp/cli": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz", - "integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "yaakcli": "bin/cli.js" - }, - "optionalDependencies": { - "@yaakapp/cli-darwin-arm64": "0.0.42", - "@yaakapp/cli-darwin-x64": "0.0.42", - "@yaakapp/cli-linux-x64": "0.0.42", - "@yaakapp/cli-win32-x64": "0.0.42" - } - }, - "node_modules/@yaakapp/cli-darwin-arm64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz", - "integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-darwin-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz", - "integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yaakapp/cli-linux-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz", - "integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==", - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yaakapp/cli-win32-x64": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz", - "integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==", - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-styles": { - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/confbox": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", - "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", - "dev": true - }, - "node_modules/jsep": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.9.tgz", - "integrity": "sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==", - "engines": { - "node": ">= 10.16.0" - } - }, - "node_modules/jsonpath-plus": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-9.0.0.tgz", - "integrity": "sha512-bqE77VIDStrOTV/czspZhTn+o27Xx9ZJRGVkdVShEtPoqsIx5yALv3lWVU6y+PqYvWPJNWE7ORCQheQkEe0DDA==", - "dependencies": { - "@jsep-plugin/assignment": "^1.2.1", - "@jsep-plugin/regex": "^1.0.3", - "jsep": "^1.3.8" - }, - "bin": { - "jsonpath": "bin/jsonpath-cli.js", - "jsonpath-plus": "bin/jsonpath-cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/local-pkg": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", - "dev": true, - "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mlly": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.0.tgz", - "integrity": "sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==", - "dev": true, - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.1.0", - "ufo": "^1.5.3" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/pkg-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz", - "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==", - "dev": true, - "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.6.1", - "pathe": "^1.1.2" - } - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true - }, - "node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true - }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", - "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", - "dev": true, - "dependencies": { - "js-tokens": "^9.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/tinybench": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", - "dev": true - }, - "node_modules/tinypool": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", - "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", - "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", - "dev": true - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/vite": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", - "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", - "dev": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", - "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", - "dev": true, - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vitest": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", - "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", - "dev": true, - "dependencies": { - "@vitest/expect": "1.6.0", - "@vitest/runner": "1.6.0", - "@vitest/snapshot": "1.6.0", - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "acorn-walk": "^8.3.2", - "chai": "^4.3.10", - "debug": "^4.3.4", - "execa": "^8.0.1", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.5.0", - "strip-literal": "^2.0.0", - "tinybench": "^2.5.1", - "tinypool": "^0.8.3", - "vite": "^5.0.0", - "vite-node": "1.6.0", - "why-is-node-running": "^2.2.2" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.6.0", - "@vitest/ui": "1.6.0", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/why-is-node-running": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", - "dev": true, - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/xpath": { - "version": "0.0.34", - "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", - "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==", - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts index 69e0145f3..ae5018a8d 100644 --- a/plugins/template-function-response/src/index.ts +++ b/plugins/template-function-response/src/index.ts @@ -1,96 +1,114 @@ import { DOMParser } from '@xmldom/xmldom'; -import { CallTemplateFunctionArgs, Context, HttpResponse, PluginDefinition } from '@yaakapp/api'; +import { + CallTemplateFunctionArgs, + Context, + HttpResponse, + PluginDefinition, + RenderPurpose, + TemplateFunctionArg, +} from '@yaakapp/api'; import { JSONPath } from 'jsonpath-plus'; import { readFileSync } from 'node:fs'; import xpath from 'xpath'; +const behaviorArg: TemplateFunctionArg = { + type: 'select', + name: 'behavior', + label: 'Sending Behavior', + defaultValue: 'smart', + options: [ + { label: 'When no responses', value: 'smart' }, + { label: 'Always', value: 'always' }, + ], +}; + +const requestArg: TemplateFunctionArg = + { + type: 'http_request', + name: 'request', + label: 'Request', + }; + export const plugin: PluginDefinition = { - templateFunctions: [{ - name: 'response', - args: [ - { - type: 'http_request', - name: 'request', - label: 'Request', + templateFunctions: [ + { + name: 'response.header', + args: [ + requestArg, + { + type: 'text', + name: 'header', + label: 'Header Name', + placeholder: 'Content-Type', + }, + behaviorArg, + ], + async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { + if (!args.values.request || !args.values.header) return null; + + const response = await getResponse(ctx, { + requestId: args.values.request, + purpose: args.purpose, + behavior: args.values.behavior ?? null, + }); + if (response == null) return null; + + const header = response.headers.find( + h => h.name.toLowerCase() === String(args.values.header ?? '').toLowerCase(), + ); + return header?.value ?? null; }, - { - type: 'text', - name: 'path', - label: 'JSONPath or XPath', - placeholder: '$.books[0].id or /books[0]/id', - }, - { - type: 'select', - name: 'behavior', - label: 'Sending Behavior', - defaultValue: 'smart', - options: [ - { name: 'When no responses', value: 'smart' }, - { name: 'Always', value: 'always' }, - ], + }, + { + name: 'response.body.path', + aliases: ['response'], + args: [ + requestArg, + { + type: 'text', + name: 'path', + label: 'JSONPath or XPath', + placeholder: '$.books[0].id or /books[0]/id', + }, + behaviorArg, + ], + async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { + if (!args.values.request || !args.values.path) return null; + + const response = await getResponse(ctx, { + requestId: args.values.request, + purpose: args.purpose, + behavior: args.values.behavior ?? null, + }); + if (response == null) return null; + + if (response.bodyPath == null) { + return null; + } + + let body; + try { + body = readFileSync(response.bodyPath, 'utf-8'); + } catch (_) { + return null; + } + + try { + return filterJSONPath(body, args.values.path); + } catch (err) { + // Probably not JSON, try XPath + } + + try { + return filterXPath(body, args.values.path); + } catch (err) { + // Probably not XML + } + + return null; // Bail out }, - ], - async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { - if (!args.values.request || !args.values.path) { - return null; - } - - const httpRequest = await ctx.httpRequest.getById({ id: args.values.request ?? 'n/a' }); - if (httpRequest == null) { - return null; - } - - const responses = await ctx.httpResponse.find({ requestId: httpRequest.id, limit: 1 }); - - if (args.values.behavior === 'never' && responses.length === 0) { - return null; - } - - let response: HttpResponse | null = responses[0] ?? null; - - // Previews happen a ton, and we don't want to send too many times on "always," so treat - // it as "smart" during preview. - let behavior = (args.values.behavior === 'always' && args.purpose === 'preview') - ? 'smart' - : args.values.behavior; - - // Send if no responses and "smart," or "always" - if ((behavior === 'smart' && response == null) || behavior === 'always') { - // NOTE: Render inside this conditional, or we'll get infinite recursion (render->render->...) - const renderedHttpRequest = await ctx.httpRequest.render({ httpRequest, purpose: args.purpose }); - response = await ctx.httpRequest.send({ httpRequest: renderedHttpRequest }); - } - - if (response == null) { - return null; - } - - if (response.bodyPath == null) { - return null; - } - - let body; - try { - body = readFileSync(response.bodyPath, 'utf-8'); - } catch (_) { - return null; - } - - try { - return filterJSONPath(body, args.values.path); - } catch (err) { - // Probably not JSON, try XPath - } - - try { - return filterXPath(body, args.values.path); - } catch (err) { - // Probably not XML - } - - return null; // Bail out }, - }], + ], }; function filterJSONPath(body: string, path: string): string { @@ -121,3 +139,39 @@ function filterXPath(body: string, path: string): string { return String(items); } } + +async function getResponse(ctx: Context, { requestId, behavior, purpose }: { + requestId: string, + behavior: string | null, + purpose: RenderPurpose, +}): Promise { + if (!requestId) return null; + + const httpRequest = await ctx.httpRequest.getById({ id: requestId ?? 'n/a' }); + if (httpRequest == null) { + return null; + } + + const responses = await ctx.httpResponse.find({ requestId: httpRequest.id, limit: 1 }); + + if (behavior === 'never' && responses.length === 0) { + return null; + } + + let response: HttpResponse | null = responses[0] ?? null; + + // Previews happen a ton, and we don't want to send too many times on "always," so treat + // it as "smart" during preview. + let finalBehavior = (behavior === 'always' && purpose === 'preview') + ? 'smart' + : behavior; + + // Send if no responses and "smart," or "always" + if ((finalBehavior === 'smart' && response == null) || finalBehavior === 'always') { + // NOTE: Render inside this conditional, or we'll get infinite recursion (render->render->...) + const renderedHttpRequest = await ctx.httpRequest.render({ httpRequest, purpose }); + response = await ctx.httpRequest.send({ httpRequest: renderedHttpRequest }); + } + + return response; +} From 929195055457c0ab9f94906d63f52e8c5f590b58 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 8 Oct 2024 14:49:03 -0700 Subject: [PATCH 041/996] Fix curl import when using boolean flags --- plugins/importer-curl/src/index.ts | 6 ++++-- plugins/importer-curl/tests/index.test.ts | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts index 00cb4ca60..a1ab8109c 100644 --- a/plugins/importer-curl/src/index.ts +++ b/plugins/importer-curl/src/index.ts @@ -27,12 +27,13 @@ const SUPPORTED_ARGS = [ ['request', 'X'], // Request method DATA_FLAGS, ].flatMap((v) => v); +const BOOL_FLAGS = ['G', 'get', 'digest']; type Pair = string | boolean; type PairsByName = Record; -export function pluginHookImport(ctx: Context, rawData: string) { +export function pluginHookImport(_ctx: Context, rawData: string) { if (!rawData.match(/^\s*curl /)) { return null; } @@ -140,11 +141,12 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { let value; const nextEntry = parseEntries[i + 1]; + const hasValue = !BOOL_FLAGS.includes(name); if (isSingleDash && name.length > 1) { // Handle squished arguments like -XPOST value = name.slice(1); name = name.slice(0, 1); - } else if (typeof nextEntry === 'string' && !nextEntry.startsWith('-')) { + } else if (typeof nextEntry === 'string' && hasValue && !nextEntry.startsWith('-')) { // Next arg is not a flag, so assign it as the value value = nextEntry; i++; // Skip next one diff --git a/plugins/importer-curl/tests/index.test.ts b/plugins/importer-curl/tests/index.test.ts index bb5362124..b01c838ef 100644 --- a/plugins/importer-curl/tests/index.test.ts +++ b/plugins/importer-curl/tests/index.test.ts @@ -196,6 +196,27 @@ describe('importer-curl', () => { }); }); + test('Imports post data into URL', () => { + expect( + pluginHookImport(ctx, 'curl -G https://api.stripe.com/v1/payment_links -d limit=3'), + ).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + method: 'GET', + url: 'https://api.stripe.com/v1/payment_links', + urlParameters: [{ + enabled: true, + name: 'limit', + value: '3', + }] + }), + ], + }, + }); + }); + test('Imports multi-line JSON', () => { expect( pluginHookImport( From 17a429525f802edd06792ca093aa5a5b7d991311 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 15 Oct 2024 07:45:45 -0700 Subject: [PATCH 042/996] Tweak plugins --- package-lock.json | 24 +++++----- package.json | 2 +- .../package.json | 2 +- .../src/index.ts | 0 plugins/template-function-prompt/src/index.ts | 4 +- .../template-function-request/package.json | 9 ---- .../template-function-request/src/index.ts | 45 ------------------- .../template-function-response/src/index.ts | 33 ++++++++++++++ 8 files changed, 50 insertions(+), 69 deletions(-) rename plugins/{template-function-file => template-function-fs}/package.json (76%) rename plugins/{template-function-file => template-function-fs}/src/index.ts (100%) delete mode 100755 plugins/template-function-request/package.json delete mode 100755 plugins/template-function-request/src/index.ts diff --git a/package-lock.json b/package-lock.json index b488ea6cd..6be73c28b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.2.15" + "@yaakapp/api": "^0.2.16" }, "devDependencies": { "@types/node": "^22.7.4", @@ -1003,9 +1003,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.15.tgz", - "integrity": "sha512-SW5S3Ca00Qo8Z/IhzCWrSQU0CZHHHCZwuDZtJkjTbfVL5Lv0DAaZsORNEIaeHyuqeQU9xRoi+Wr/WHoA3bG6+A==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.16.tgz", + "integrity": "sha512-rooweCKOMsqbTdSlb4vxe3wL19PpkVualZrtWvRelnUhIPgcJR8EMVNn/K2tZfLGKOXnthZi9xgFBeARnOyuSw==", "dependencies": { "@types/node": "^22.5.4" } @@ -1042,8 +1042,8 @@ "resolved": "plugins/importer-yaak", "link": true }, - "node_modules/@yaakapp/template-function-file": { - "resolved": "plugins/template-function-file", + "node_modules/@yaakapp/template-function-fs": { + "resolved": "plugins/template-function-fs", "link": true }, "node_modules/@yaakapp/template-function-hash": { @@ -1054,10 +1054,6 @@ "resolved": "plugins/template-function-prompt", "link": true }, - "node_modules/@yaakapp/template-function-request": { - "resolved": "plugins/template-function-request", - "link": true - }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -6702,6 +6698,11 @@ }, "plugins/template-function-file": { "name": "@yaakapp/template-function-file", + "version": "0.0.1", + "extraneous": true + }, + "plugins/template-function-fs": { + "name": "@yaakapp/template-function-fs", "version": "0.0.1" }, "plugins/template-function-hash": { @@ -6714,7 +6715,8 @@ }, "plugins/template-function-request": { "name": "@yaakapp/template-function-request", - "version": "0.0.1" + "version": "0.0.1", + "extraneous": true }, "plugins/template-function-response": { "version": "0.0.1", diff --git a/package.json b/package.json index 1633ca27a..e6bc3adee 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.2.15" + "@yaakapp/api": "^0.2.16" } } diff --git a/plugins/template-function-file/package.json b/plugins/template-function-fs/package.json similarity index 76% rename from plugins/template-function-file/package.json rename to plugins/template-function-fs/package.json index 59aea7ab3..44e596009 100644 --- a/plugins/template-function-file/package.json +++ b/plugins/template-function-fs/package.json @@ -1,5 +1,5 @@ { - "name": "@yaakapp/template-function-file", + "name": "@yaakapp/template-function-fs", "private": true, "version": "0.0.1", "scripts": { diff --git a/plugins/template-function-file/src/index.ts b/plugins/template-function-fs/src/index.ts similarity index 100% rename from plugins/template-function-file/src/index.ts rename to plugins/template-function-fs/src/index.ts diff --git a/plugins/template-function-prompt/src/index.ts b/plugins/template-function-prompt/src/index.ts index 4941253ff..957bc8fff 100644 --- a/plugins/template-function-prompt/src/index.ts +++ b/plugins/template-function-prompt/src/index.ts @@ -3,9 +3,9 @@ import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/ap export const plugin: PluginDefinition = { templateFunctions: [{ name: 'prompt.text', + description: 'Prompt the user for input when sending a request', args: [ { type: 'text', name: 'title', label: 'Title' }, - { type: 'text', name: 'label', label: 'Label', optional: true }, { type: 'text', name: 'defaultValue', label: 'Default Value', optional: true }, { type: 'text', name: 'placeholder', label: 'Placeholder', optional: true }, ], @@ -14,7 +14,7 @@ export const plugin: PluginDefinition = { return await ctx.prompt.text({ id: `prompt-${args.values.label}`, - label: args.values.label ?? '', + label: args.values.title ?? '', title: args.values.title ?? '', defaultValue: args.values.defaultValue, placeholder: args.values.placeholder, diff --git a/plugins/template-function-request/package.json b/plugins/template-function-request/package.json deleted file mode 100755 index a3ebb038d..000000000 --- a/plugins/template-function-request/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@yaakapp/template-function-request", - "private": true, - "version": "0.0.1", - "scripts": { - "build": "yaakcli build ./src/index.ts", - "dev": "yaakcli dev ./src/index.js" - } -} diff --git a/plugins/template-function-request/src/index.ts b/plugins/template-function-request/src/index.ts deleted file mode 100755 index 0567d5871..000000000 --- a/plugins/template-function-request/src/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; - -export const plugin: PluginDefinition = { - templateFunctions: [ - { - name: 'request.body', - args: [{ - name: 'requestId', - label: 'Http Request', - type: 'http_request', - }], - async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { - const httpRequest = await ctx.httpRequest.getById({ id: args.values.requestId ?? 'n/a' }); - if (httpRequest == null) return null; - return String(await ctx.templates.render({ - data: httpRequest.body?.text ?? '', - purpose: args.purpose, - })); - }, - }, - { - name: 'request.header', - args: [ - { - name: 'requestId', - label: 'Http Request', - type: 'http_request', - }, - { - name: 'header', - label: 'Header Name', - type: 'text', - }], - async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { - const httpRequest = await ctx.httpRequest.getById({ id: args.values.requestId ?? 'n/a' }); - if (httpRequest == null) return null; - const header = httpRequest.headers.find(h => h.name.toLowerCase() === args.values.header?.toLowerCase()); - return String(await ctx.templates.render({ - data: header?.value ?? '', - purpose: args.purpose, - })); - }, - }, - ], -}; diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts index ae5018a8d..2080cd985 100644 --- a/plugins/template-function-response/src/index.ts +++ b/plugins/template-function-response/src/index.ts @@ -61,6 +61,7 @@ export const plugin: PluginDefinition = { }, { name: 'response.body.path', + description: 'Access a field of the response body using JsonPath or XPath', aliases: ['response'], args: [ requestArg, @@ -108,6 +109,38 @@ export const plugin: PluginDefinition = { return null; // Bail out }, }, + { + name: 'response.body.raw', + description: 'Access the entire response body, as text', + aliases: ['response'], + args: [ + requestArg, + behaviorArg, + ], + async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { + if (!args.values.request) return null; + + const response = await getResponse(ctx, { + requestId: args.values.request, + purpose: args.purpose, + behavior: args.values.behavior ?? null, + }); + if (response == null) return null; + + if (response.bodyPath == null) { + return null; + } + + let body; + try { + body = readFileSync(response.bodyPath, 'utf-8'); + } catch (_) { + return null; + } + + return body; + }, + }, ], }; From 9d24aefba186d1c3ebec6eeec90eba2a66435a98 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 15 Oct 2024 07:47:26 -0700 Subject: [PATCH 043/996] Add template function descriptions --- plugins/template-function-fs/src/index.ts | 1 + plugins/template-function-hash/src/index.ts | 1 + plugins/template-function-response/src/index.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/plugins/template-function-fs/src/index.ts b/plugins/template-function-fs/src/index.ts index 472c1a0d9..c783ea4f2 100644 --- a/plugins/template-function-fs/src/index.ts +++ b/plugins/template-function-fs/src/index.ts @@ -4,6 +4,7 @@ import fs from 'node:fs'; export const plugin: PluginDefinition = { templateFunctions: [{ name: 'fs.readFile', + description: 'Read the contents of a file as utf-8', args: [{ title: 'Select File', type: 'file', name: 'path', label: 'File' }], async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { if (!args.values.path) return null; diff --git a/plugins/template-function-hash/src/index.ts b/plugins/template-function-hash/src/index.ts index 8520c0b78..9fca36a4f 100755 --- a/plugins/template-function-hash/src/index.ts +++ b/plugins/template-function-hash/src/index.ts @@ -6,6 +6,7 @@ const algorithms = ['md5', 'sha1', 'sha256', 'sha512']; export const plugin: PluginDefinition = { templateFunctions: algorithms.map(algorithm => ({ name: `hash.${algorithm}`, + description: 'Hash a value to its hexidecimal representation', args: [ { name: 'input', diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts index 2080cd985..90bb65253 100644 --- a/plugins/template-function-response/src/index.ts +++ b/plugins/template-function-response/src/index.ts @@ -33,6 +33,7 @@ export const plugin: PluginDefinition = { templateFunctions: [ { name: 'response.header', + description: 'Read the value of a response header, by name', args: [ requestArg, { From d91e60f7e08916d13e003c1785be2bf327204368 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 22 Oct 2024 07:26:16 -0700 Subject: [PATCH 044/996] Support new GraphQL body type in curl export --- plugins/exporter-curl/src/index.ts | 7 +++++-- plugins/exporter-curl/tests/index.test.ts | 20 ++++++++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts index 97814c823..5fdbdaf7c 100644 --- a/plugins/exporter-curl/src/index.ts +++ b/plugins/exporter-curl/src/index.ts @@ -51,9 +51,12 @@ export async function pluginHookExport(_ctx: Context, request: Partial { ); }); + test('Exports POST with GraphQL data', async () => { + expect( + await pluginHookExport(ctx, { + url: 'https://yaak.app', + method: 'POST', + bodyType: 'graphql', + body: { + query : '{foo,bar}', + variables: {a: 'aaa', b: 'bbb'}, + }, + }), + ).toEqual( + [`curl -X POST 'https://yaak.app'`, `--data-raw '{"query":"{foo,bar}","variables":{"a":"aaa","b":"bbb"}}'`].join(` \\\n `), + ); + }); + test('Exports PUT with multipart form', async () => { expect( await pluginHookExport(ctx, { @@ -78,7 +94,7 @@ describe('exporter-curl', () => { [ `curl -X POST 'https://yaak.app'`, `--header 'Content-Type: application/json'`, - `--data-raw $'{"foo":"bar\\'s"}'`, + `--data-raw '{"foo":"bar\\'s"}'`, ].join(` \\\n `), ); }); @@ -98,7 +114,7 @@ describe('exporter-curl', () => { [ `curl -X POST 'https://yaak.app'`, `--header 'Content-Type: application/json'`, - `--data-raw $'{"foo":"bar",\n"baz":"qux"}'`, + `--data-raw '{"foo":"bar",\n"baz":"qux"}'`, ].join(` \\\n `), ); }); From 59b0b7321f9ac3549a6735835673d67b9c8b7a51 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 22 Oct 2024 07:41:28 -0700 Subject: [PATCH 045/996] Fix GraphQL variables --- plugins/exporter-curl/src/index.ts | 10 +++++++++- plugins/exporter-curl/tests/index.test.ts | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts index 5fdbdaf7c..3c21682f3 100644 --- a/plugins/exporter-curl/src/index.ts +++ b/plugins/exporter-curl/src/index.ts @@ -52,7 +52,7 @@ export async function pluginHookExport(_ctx: Context, request: Partial { bodyType: 'graphql', body: { query : '{foo,bar}', - variables: {a: 'aaa', b: 'bbb'}, + variables: '{"a": "aaa", "b": "bbb"}', }, }), ).toEqual( From ab48f118af3988e70859fdb37afa69c9cbe509d1 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 22 Oct 2024 08:05:58 -0700 Subject: [PATCH 046/996] Handle no GraphQL variables --- plugins/exporter-curl/src/index.ts | 2 +- plugins/exporter-curl/tests/index.test.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts index 3c21682f3..c4f06a026 100644 --- a/plugins/exporter-curl/src/index.ts +++ b/plugins/exporter-curl/src/index.ts @@ -52,7 +52,7 @@ export async function pluginHookExport(_ctx: Context, request: Partial { ); }); + test('Exports POST with GraphQL data no variables', async () => { + expect( + await pluginHookExport(ctx, { + url: 'https://yaak.app', + method: 'POST', + bodyType: 'graphql', + body: { + query : '{foo,bar}', + }, + }), + ).toEqual( + [`curl -X POST 'https://yaak.app'`, `--data-raw '{"query":"{foo,bar}"}'`].join(` \\\n `), + ); + }); + test('Exports PUT with multipart form', async () => { expect( await pluginHookExport(ctx, { From f8b211be1c06f8d9b2ee035adc69364c014b9cec Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 31 Dec 2024 07:21:14 -0800 Subject: [PATCH 047/996] Support --url-query in curl import --- plugins/importer-curl/src/index.ts | 80 +++++++++++++---------- plugins/importer-curl/tests/index.test.ts | 17 +++++ 2 files changed, 64 insertions(+), 33 deletions(-) diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts index a1ab8109c..db3e77ce4 100644 --- a/plugins/importer-curl/src/index.ts +++ b/plugins/importer-curl/src/index.ts @@ -11,27 +11,29 @@ interface ExportResources { } const DATA_FLAGS = ['d', 'data', 'data-raw', 'data-urlencode', 'data-binary', 'data-ascii']; -const SUPPORTED_ARGS = [ - ['url'], // Specify the URL explicitly - ['user', 'u'], // Authentication - ['digest'], // Apply auth as digest - ['header', 'H'], +const SUPPORTED_FLAGS = [ ['cookie', 'b'], - ['get', 'G'], // Put the post data in the URL ['d', 'data'], // Add url encoded data + ['data-ascii'], + ['data-binary'], ['data-raw'], ['data-urlencode'], - ['data-binary'], - ['data-ascii'], + ['digest'], // Apply auth as digest ['form', 'F'], // Add multipart data + ['get', 'G'], // Put the post data in the URL + ['header', 'H'], ['request', 'X'], // Request method + ['url'], // Specify the URL explicitly + ['url-query'], + ['user', 'u'], // Authentication DATA_FLAGS, ].flatMap((v) => v); -const BOOL_FLAGS = ['G', 'get', 'digest']; -type Pair = string | boolean; +const BOOLEAN_FLAGS = ['G', 'get', 'digest']; -type PairsByName = Record; +type FlagValue = string | boolean; + +type FlagsByName = Record; export function pluginHookImport(_ctx: Context, rawData: string) { if (!rawData.match(/^\s*curl /)) { @@ -121,7 +123,7 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { // ~~~~~~~~~~~~~~~~~~~~~ // // Collect all the flags // // ~~~~~~~~~~~~~~~~~~~~~ // - const pairsByName: PairsByName = {}; + const flagsByName: FlagsByName = {}; const singletons: ParseEntry[] = []; // Start at 1 so we can skip the ^curl part @@ -135,13 +137,13 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { const isSingleDash = parseEntry[0] === '-' && parseEntry[1] !== '-'; let name = parseEntry.replace(/^-{1,2}/, ''); - if (!SUPPORTED_ARGS.includes(name)) { + if (!SUPPORTED_FLAGS.includes(name)) { continue; } let value; const nextEntry = parseEntries[i + 1]; - const hasValue = !BOOL_FLAGS.includes(name); + const hasValue = !BOOLEAN_FLAGS.includes(name); if (isSingleDash && name.length > 1) { // Handle squished arguments like -XPOST value = name.slice(1); @@ -154,8 +156,8 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { value = true; } - pairsByName[name] = pairsByName[name] || []; - pairsByName[name]!.push(value); + flagsByName[name] = flagsByName[name] || []; + flagsByName[name]!.push(value); } else if (parseEntry) { singletons.push(parseEntry); } @@ -165,12 +167,11 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { // Build the request // // ~~~~~~~~~~~~~~~~~ // - // Url & parameters - + // Url and Parameters let urlParameters: HttpUrlParameter[]; let url: string; - const urlArg = getPairValue(pairsByName, (singletons[0] as string) || '', ['url']); + const urlArg = getPairValue(flagsByName, (singletons[0] as string) || '', ['url']); const [baseUrl, search] = splitOnce(urlArg, '?'); urlParameters = search?.split('&').map((p) => { @@ -180,10 +181,23 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { url = baseUrl ?? urlArg; + // Query params + for (const p of flagsByName['url-query'] ?? []) { + if (typeof p !== 'string') { + continue; + } + const [name, value] = p.split('='); + urlParameters.push({ + name: name ?? '', + value: value ?? '', + enabled: true, + }); + } + // Authentication - const [username, password] = getPairValue(pairsByName, '', ['u', 'user']).split(/:(.*)$/); + const [username, password] = getPairValue(flagsByName, '', ['u', 'user']).split(/:(.*)$/); - const isDigest = getPairValue(pairsByName, false, ['digest']); + const isDigest = getPairValue(flagsByName, false, ['digest']); const authenticationType = username ? (isDigest ? 'digest' : 'basic') : null; const authentication = username ? { @@ -194,8 +208,8 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { // Headers const headers = [ - ...((pairsByName['header'] as string[] | undefined) || []), - ...((pairsByName['H'] as string[] | undefined) || []), + ...((flagsByName['header'] as string[] | undefined) || []), + ...((flagsByName['H'] as string[] | undefined) || []), ].map((header) => { const [name, value] = header.split(/:(.*)$/); // remove final colon from header name if present @@ -215,8 +229,8 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { // Cookies const cookieHeaderValue = [ - ...((pairsByName['cookie'] as string[] | undefined) || []), - ...((pairsByName['b'] as string[] | undefined) || []), + ...((flagsByName['cookie'] as string[] | undefined) || []), + ...((flagsByName['b'] as string[] | undefined) || []), ] .map((str) => { const name = str.split('=', 1)[0]; @@ -240,15 +254,15 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { }); } - ///Body (Text or Blob) - const dataParameters = pairsToDataParameters(pairsByName); + // Body (Text or Blob) + const dataParameters = pairsToDataParameters(flagsByName); const contentTypeHeader = headers.find((header) => header.name.toLowerCase() === 'content-type'); const mimeType = contentTypeHeader ? contentTypeHeader.value.split(';')[0] : null; // Body (Multipart Form Data) const formDataParams = [ - ...((pairsByName['form'] as string[] | undefined) || []), - ...((pairsByName['F'] as string[] | undefined) || []), + ...((flagsByName['form'] as string[] | undefined) || []), + ...((flagsByName['F'] as string[] | undefined) || []), ].map((str) => { const parts = str.split('='); const name = parts[0] ?? ''; @@ -270,7 +284,7 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { // Body let body = {}; let bodyType: string | null = null; - const bodyAsGET = getPairValue(pairsByName, false, ['G', 'get']); + const bodyAsGET = getPairValue(flagsByName, false, ['G', 'get']); if (dataParameters.length > 0 && bodyAsGET) { urlParameters.push(...dataParameters); @@ -316,7 +330,7 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { } // Method - let method = getPairValue(pairsByName, '', ['X', 'request']).toUpperCase(); + let method = getPairValue(flagsByName, '', ['X', 'request']).toUpperCase(); if (method === '' && body) { method = 'text' in body || 'form' in body ? 'POST' : 'GET'; @@ -350,7 +364,7 @@ interface DataParameter { enabled?: boolean; } -function pairsToDataParameters(keyedPairs: PairsByName): DataParameter[] { +function pairsToDataParameters(keyedPairs: FlagsByName): DataParameter[] { let dataParameters: DataParameter[] = []; for (const flagName of DATA_FLAGS) { @@ -386,7 +400,7 @@ function pairsToDataParameters(keyedPairs: PairsByName): DataParameter[] { } const getPairValue = ( - pairsByName: PairsByName, + pairsByName: FlagsByName, defaultValue: T, names: string[], ) => { diff --git a/plugins/importer-curl/tests/index.test.ts b/plugins/importer-curl/tests/index.test.ts index b01c838ef..862faa6bc 100644 --- a/plugins/importer-curl/tests/index.test.ts +++ b/plugins/importer-curl/tests/index.test.ts @@ -310,6 +310,23 @@ describe('importer-curl', () => { }); }); + test('Imports query params', () => { + expect(pluginHookImport(ctx, 'curl "https://yaak.app" --url-query foo=bar --url-query baz=qux')).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + urlParameters: [ + { name: 'foo', value: 'bar', enabled: true }, + { name: 'baz', value: 'qux', enabled: true }, + ], + }), + ], + }, + }); + }); + test('Imports query params from the URL', () => { expect(pluginHookImport(ctx, 'curl "https://yaak.app?foo=bar&baz=a%20a"')).toEqual({ resources: { From a80a25a90e81fdd8c835f9cc8febe89d995ceb57 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 13 Jan 2025 17:04:35 -0800 Subject: [PATCH 048/996] Update for standalone base environments --- package-lock.json | 8 +- package.json | 2 +- plugins/importer-insomnia/src/index.ts | 79 ++++---- .../tests/fixtures/basic.input.json | 187 ++++++++++++++++++ .../tests/fixtures/basic.output.json | 117 +++++++++++ plugins/importer-insomnia/tests/index.test.ts | 26 +++ plugins/importer-postman/src/index.ts | 32 ++- .../tests/fixtures/nested.output.json | 14 +- .../tests/fixtures/params.output.json | 12 +- plugins/importer-yaak/src/index.ts | 27 ++- plugins/importer-yaak/tests/index.test.ts | 42 ++++ 11 files changed, 495 insertions(+), 51 deletions(-) create mode 100644 plugins/importer-insomnia/tests/fixtures/basic.input.json create mode 100644 plugins/importer-insomnia/tests/fixtures/basic.output.json create mode 100644 plugins/importer-insomnia/tests/index.test.ts diff --git a/package-lock.json b/package-lock.json index 6be73c28b..b3b9a7c2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.2.16" + "@yaakapp/api": "^0.2.17" }, "devDependencies": { "@types/node": "^22.7.4", @@ -1003,9 +1003,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.16.tgz", - "integrity": "sha512-rooweCKOMsqbTdSlb4vxe3wL19PpkVualZrtWvRelnUhIPgcJR8EMVNn/K2tZfLGKOXnthZi9xgFBeARnOyuSw==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.17.tgz", + "integrity": "sha512-4ldxDxz2x4WCl4LR/D8Z6zyQGuMhBX3c4eMGDqxCjtEd5tXWaKJYQBEdi/Hp2FG0NSPNBEtyVfZd52sGfiqBoA==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/package.json b/package.json index e6bc3adee..abcc0fa73 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.2.16" + "@yaakapp/api": "^0.2.17" } } diff --git a/plugins/importer-insomnia/src/index.ts b/plugins/importer-insomnia/src/index.ts index 9f320b593..12d53c471 100644 --- a/plugins/importer-insomnia/src/index.ts +++ b/plugins/importer-insomnia/src/index.ts @@ -1,4 +1,4 @@ -import { Environment, Folder, GrpcRequest, HttpRequest, Workspace, Context } from '@yaakapp/api'; +import { Context, Environment, Folder, GrpcRequest, HttpRequest, Workspace } from '@yaakapp/api'; import YAML from 'yaml'; type AtLeast = Partial & Pick; @@ -16,11 +16,13 @@ export function pluginHookImport(ctx: Context, contents: string) { try { parsed = JSON.parse(contents); - } catch (e) {} + } catch (e) { + } try { parsed = parsed ?? YAML.parse(contents); - } catch (e) { } + } catch (e) { + } if (!isJSObject(parsed)) return; if (!Array.isArray(parsed.resources)) return; @@ -35,23 +37,20 @@ export function pluginHookImport(ctx: Context, contents: string) { // Import workspaces const workspacesToImport = parsed.resources.filter(isWorkspace); - for (const workspaceToImport of workspacesToImport) { - const baseEnvironment = parsed.resources.find( - (r: any) => isEnvironment(r) && r.parentId === workspaceToImport._id, - ); + for (const w of workspacesToImport) { resources.workspaces.push({ - id: convertId(workspaceToImport._id), - createdAt: new Date(workspacesToImport.created ?? Date.now()).toISOString().replace('Z', ''), - updatedAt: new Date(workspacesToImport.updated ?? Date.now()).toISOString().replace('Z', ''), + id: convertId(w._id), + createdAt: w.created ? new Date(w.created).toISOString().replace('Z', '') : undefined, + updatedAt: w.updated ? new Date(w.updated).toISOString().replace('Z', '') : undefined, model: 'workspace', - name: workspaceToImport.name, - variables: baseEnvironment ? parseVariables(baseEnvironment.data) : [], + name: w.name, + description: w.description || undefined, }); const environmentsToImport = parsed.resources.filter( - (r: any) => isEnvironment(r) && r.parentId === baseEnvironment?._id, + (r: any) => isEnvironment(r), ); resources.environments.push( - ...environmentsToImport.map((r: any) => importEnvironment(r, workspaceToImport._id)), + ...environmentsToImport.map((r: any) => importEnvironment(r, w._id)), ); const nextFolder = (parentId: string) => { @@ -59,22 +58,22 @@ export function pluginHookImport(ctx: Context, contents: string) { let sortPriority = 0; for (const child of children) { if (isRequestGroup(child)) { - resources.folders.push(importFolder(child, workspaceToImport._id)); + resources.folders.push(importFolder(child, w._id)); nextFolder(child._id); } else if (isHttpRequest(child)) { resources.httpRequests.push( - importHttpRequest(child, workspaceToImport._id, sortPriority++), + importHttpRequest(child, w._id, sortPriority++), ); } else if (isGrpcRequest(child)) { resources.grpcRequests.push( - importGrpcRequest(child, workspaceToImport._id, sortPriority++), + importGrpcRequest(child, w._id, sortPriority++), ); } } }; // Import folders - nextFolder(workspaceToImport._id); + nextFolder(w._id); } // Filter out any `null` values @@ -83,15 +82,16 @@ export function pluginHookImport(ctx: Context, contents: string) { resources.environments = resources.environments.filter(Boolean); resources.workspaces = resources.workspaces.filter(Boolean); - return { resources }; + return { resources: deleteUndefinedAttrs(resources) }; } function importEnvironment(e: any, workspaceId: string): ExportResources['environments'][0] { return { id: convertId(e._id), - createdAt: new Date(e.created ?? Date.now()).toISOString().replace('Z', ''), - updatedAt: new Date(e.updated ?? Date.now()).toISOString().replace('Z', ''), + createdAt: e.created ? new Date(e.created).toISOString().replace('Z', '') : undefined, + updatedAt: e.updated ? new Date(e.updated).toISOString().replace('Z', '') : undefined, workspaceId: convertId(workspaceId), + environmentId: e.parentId === workspaceId ? null : convertId(e.parentId), model: 'environment', name: e.name, variables: Object.entries(e.data).map(([name, value]) => ({ @@ -105,10 +105,11 @@ function importEnvironment(e: any, workspaceId: string): ExportResources['enviro function importFolder(f: any, workspaceId: string): ExportResources['folders'][0] { return { id: convertId(f._id), - createdAt: new Date(f.created ?? Date.now()).toISOString().replace('Z', ''), - updatedAt: new Date(f.updated ?? Date.now()).toISOString().replace('Z', ''), + createdAt: f.created ? new Date(f.created).toISOString().replace('Z', '') : undefined, + updatedAt: f.updated ? new Date(f.updated).toISOString().replace('Z', '') : undefined, folderId: f.parentId === workspaceId ? null : convertId(f.parentId), workspaceId: convertId(workspaceId), + description: f.description || undefined, model: 'folder', name: f.name, }; @@ -125,13 +126,14 @@ function importGrpcRequest( return { id: convertId(r._id), - createdAt: new Date(r.created ?? Date.now()).toISOString().replace('Z', ''), - updatedAt: new Date(r.updated ?? Date.now()).toISOString().replace('Z', ''), + createdAt: r.created ? new Date(r.created).toISOString().replace('Z', '') : undefined, + updatedAt: r.updated ? new Date(r.updated).toISOString().replace('Z', '') : undefined, workspaceId: convertId(workspaceId), folderId: r.parentId === workspaceId ? null : convertId(r.parentId), model: 'grpc_request', sortPriority, name: r.name, + description: r.description || undefined, url: convertSyntax(r.url), service, method, @@ -200,13 +202,14 @@ function importHttpRequest( return { id: convertId(r._id), - createdAt: new Date(r.created ?? Date.now()).toISOString().replace('Z', ''), - updatedAt: new Date(r.updated ?? Date.now()).toISOString().replace('Z', ''), + createdAt: r.created ? new Date(r.created).toISOString().replace('Z', '') : undefined, + updatedAt: r.updated ? new Date(r.updated).toISOString().replace('Z', '') : undefined, workspaceId: convertId(workspaceId), folderId: r.parentId === workspaceId ? null : convertId(r.parentId), model: 'http_request', sortPriority, name: r.name, + description: r.description || undefined, url: convertSyntax(r.url), body, bodyType, @@ -223,14 +226,6 @@ function importHttpRequest( }; } -function parseVariables(data: Record) { - return Object.entries(data).map(([name, value]) => ({ - enabled: true, - name, - value: `${value}`, - })); -} - function convertSyntax(variable: string): string { if (!isJSString(variable)) return variable; return variable.replaceAll(/{{\s*(_\.)?([^}]+)\s*}}/g, '${[$2]}'); @@ -270,3 +265,17 @@ function convertId(id: string): string { } return `GENERATE_ID::${id}`; } + +function deleteUndefinedAttrs(obj: T): T { + if (Array.isArray(obj) && obj != null) { + return obj.map(deleteUndefinedAttrs) as T; + } else if (typeof obj === 'object' && obj != null) { + return Object.fromEntries( + Object.entries(obj) + .filter(([, v]) => v !== undefined) + .map(([k, v]) => [k, deleteUndefinedAttrs(v)]), + ) as T; + } else { + return obj; + } +} diff --git a/plugins/importer-insomnia/tests/fixtures/basic.input.json b/plugins/importer-insomnia/tests/fixtures/basic.input.json new file mode 100644 index 000000000..cb0568e51 --- /dev/null +++ b/plugins/importer-insomnia/tests/fixtures/basic.input.json @@ -0,0 +1,187 @@ +{ + "_type": "export", + "__export_format": 4, + "__export_date": "2025-01-13T15:19:18.330Z", + "__export_source": "insomnia.desktop.app:v10.3.0", + "resources": [ + { + "_id": "req_84cd9ae4bd034dd8bb730e856a665cbb", + "parentId": "fld_859d1df78261463480b6a3a1419517e3", + "modified": 1736781473176, + "created": 1736781406672, + "url": "{{ _.BASE_URL }}/foo/:id", + "name": "New Request", + "description": "My description of the request", + "method": "GET", + "body": { + "mimeType": "multipart/form-data", + "params": [ + { + "id": "pair_7c86036ae8ef499dbbc0b43d0800c5a3", + "name": "form", + "value": "data", + "description": "", + "disabled": false + } + ] + }, + "parameters": [ + { + "id": "pair_b22f6ff611cd4250a6e405ca7b713d09", + "name": "query", + "value": "qqq", + "description": "", + "disabled": false + } + ], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data", + "id": "pair_4af845963bd14256b98716617971eecd" + }, + { + "name": "User-Agent", + "value": "insomnia/10.3.0", + "id": "pair_535ffd00ce48462cb1b7258832ade65a" + }, + { + "id": "pair_ab4b870278e943cba6babf5a73e213e3", + "name": "X-Header", + "value": "xxxx", + "description": "", + "disabled": false + } + ], + "authentication": { + "type": "basic", + "useISO88591": false, + "disabled": false, + "username": "user", + "password": "pass" + }, + "metaSortKey": -1736781406672, + "isPrivate": false, + "pathParameters": [ + { + "name": "id", + "value": "iii" + } + ], + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "fld_859d1df78261463480b6a3a1419517e3", + "parentId": "wrk_d4d92f7c0ee947b89159243506687019", + "modified": 1736781404718, + "created": 1736781404718, + "name": "Top Level", + "description": "", + "environment": {}, + "environmentPropertyOrder": null, + "metaSortKey": -1736781404718, + "environmentType": "kv", + "_type": "request_group" + }, + { + "_id": "wrk_d4d92f7c0ee947b89159243506687019", + "parentId": null, + "modified": 1736781343765, + "created": 1736781343765, + "name": "Dummy", + "description": "", + "scope": "collection", + "_type": "workspace" + }, + { + "_id": "env_16c0dec5b77c414ae0e419b8f10c3701300c5900", + "parentId": "wrk_d4d92f7c0ee947b89159243506687019", + "modified": 1736781355209, + "created": 1736781343767, + "name": "Base Environment", + "data": { + "BASE_VAR": "hello" + }, + "dataPropertyOrder": null, + "color": null, + "isPrivate": false, + "metaSortKey": 1736781343767, + "environmentType": "kv", + "kvPairData": [ + { + "id": "envPair_61c1be66d42241b5a28306d2cd92d3e3", + "name": "BASE_VAR", + "value": "hello", + "type": "str", + "enabled": true + } + ], + "_type": "environment" + }, + { + "_id": "jar_16c0dec5b77c414ae0e419b8f10c3701300c5900", + "parentId": "wrk_d4d92f7c0ee947b89159243506687019", + "modified": 1736781343768, + "created": 1736781343768, + "name": "Default Jar", + "cookies": [], + "_type": "cookie_jar" + }, + { + "_id": "env_799ae3d723ef44af91b4817e5d057e6d", + "parentId": "env_16c0dec5b77c414ae0e419b8f10c3701300c5900", + "modified": 1736781394705, + "created": 1736781358515, + "name": "Production", + "data": { + "BASE_URL": "https://api.yaak.app" + }, + "dataPropertyOrder": null, + "color": "#f22c2c", + "isPrivate": false, + "metaSortKey": 1736781358515, + "environmentType": "kv", + "kvPairData": [ + { + "id": "envPair_4d97b569b7e845ccbf488e1b26637cbc", + "name": "BASE_URL", + "value": "https://api.yaak.app", + "type": "str", + "enabled": true + } + ], + "_type": "environment" + }, + { + "_id": "env_030fbfdbb274426ebd78e2e6518f8553", + "parentId": "env_16c0dec5b77c414ae0e419b8f10c3701300c5900", + "modified": 1736781391078, + "created": 1736781374707, + "name": "Staging", + "data": { + "BASE_URL": "https://api.staging.yaak.app" + }, + "dataPropertyOrder": null, + "color": "#206fac", + "isPrivate": false, + "metaSortKey": 1736781358565, + "environmentType": "kv", + "kvPairData": [ + { + "id": "envPair_4d97b569b7e845ccbf488e1b26637cbc", + "name": "BASE_URL", + "value": "https://api.staging.yaak.app", + "type": "str", + "enabled": true + } + ], + "_type": "environment" + } + ] +} diff --git a/plugins/importer-insomnia/tests/fixtures/basic.output.json b/plugins/importer-insomnia/tests/fixtures/basic.output.json new file mode 100644 index 000000000..f989ec0e8 --- /dev/null +++ b/plugins/importer-insomnia/tests/fixtures/basic.output.json @@ -0,0 +1,117 @@ +{ + "resources": { + "environments": [ + { + "createdAt": "2025-01-13T15:15:43.767", + "environmentId": null, + "id": "GENERATE_ID::env_16c0dec5b77c414ae0e419b8f10c3701300c5900", + "model": "environment", + "name": "Base Environment", + "variables": [ + { + "enabled": true, + "name": "BASE_VAR", + "value": "hello" + } + ], + "workspaceId": "GENERATE_ID::wrk_d4d92f7c0ee947b89159243506687019" + }, + { + "createdAt": "2025-01-13T15:15:58.515", + "environmentId": "GENERATE_ID::env_16c0dec5b77c414ae0e419b8f10c3701300c5900", + "id": "GENERATE_ID::env_799ae3d723ef44af91b4817e5d057e6d", + "model": "environment", + "name": "Production", + "variables": [ + { + "enabled": true, + "name": "BASE_URL", + "value": "https://api.yaak.app" + } + ], + "workspaceId": "GENERATE_ID::wrk_d4d92f7c0ee947b89159243506687019" + }, + { + "createdAt": "2025-01-13T15:16:14.707", + "environmentId": "GENERATE_ID::env_16c0dec5b77c414ae0e419b8f10c3701300c5900", + "id": "GENERATE_ID::env_030fbfdbb274426ebd78e2e6518f8553", + "model": "environment", + "name": "Staging", + "variables": [ + { + "enabled": true, + "name": "BASE_URL", + "value": "https://api.staging.yaak.app" + } + ], + "workspaceId": "GENERATE_ID::wrk_d4d92f7c0ee947b89159243506687019" + } + ], + "folders": [ + { + "createdAt": "2025-01-13T15:16:44.718", + "folderId": null, + "id": "GENERATE_ID::fld_859d1df78261463480b6a3a1419517e3", + "model": "folder", + "name": "Top Level", + "workspaceId": "GENERATE_ID::wrk_d4d92f7c0ee947b89159243506687019" + } + ], + "grpcRequests": [], + "httpRequests": [ + { + "authentication": { + "password": "pass", + "username": "user" + }, + "authenticationType": "basic", + "body": { + "form": [ + { + "enabled": true, + "file": null, + "name": "form", + "value": "data" + } + ] + }, + "bodyType": "multipart/form-data", + "createdAt": "2025-01-13T15:16:46.672", + "description": "My description of the request", + "folderId": "GENERATE_ID::fld_859d1df78261463480b6a3a1419517e3", + "headers": [ + { + "enabled": true, + "name": "Content-Type", + "value": "multipart/form-data" + }, + { + "enabled": true, + "name": "User-Agent", + "value": "insomnia/10.3.0" + }, + { + "enabled": true, + "name": "X-Header", + "value": "xxxx" + } + ], + "id": "GENERATE_ID::req_84cd9ae4bd034dd8bb730e856a665cbb", + "method": "GET", + "model": "http_request", + "name": "New Request", + "sortPriority": 0, + "url": "${[BASE_URL ]}/foo/:id", + "workspaceId": "GENERATE_ID::wrk_d4d92f7c0ee947b89159243506687019" + } + ], + "workspaces": [ + { + "createdAt": "2025-01-13T15:15:43.765", + "id": "GENERATE_ID::wrk_d4d92f7c0ee947b89159243506687019", + "model": "workspace", + "name": "Dummy" + } + ] + } +} diff --git a/plugins/importer-insomnia/tests/index.test.ts b/plugins/importer-insomnia/tests/index.test.ts new file mode 100644 index 000000000..fe073717b --- /dev/null +++ b/plugins/importer-insomnia/tests/index.test.ts @@ -0,0 +1,26 @@ +import { Context } from '@yaakapp/api'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { describe, expect, test } from 'vitest'; +import { pluginHookImport } from '../src'; + +const ctx = {} as Context; + +describe('importer-yaak', () => { + const p = path.join(__dirname, 'fixtures'); + const fixtures = fs.readdirSync(p); + + for (const fixture of fixtures) { + if (fixture.includes('.output')) { + continue; + } + + test('Imports ' + fixture, () => { + const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); + const expected = fs.readFileSync(path.join(p, fixture.replace('.input', '.output')), 'utf-8'); + const result = pluginHookImport(ctx, contents); + // console.log(JSON.stringify(result, null, 2)) + expect(result).toEqual(JSON.parse(expected)); + }); + } +}); diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts index b4376aa90..93c25348b 100644 --- a/plugins/importer-postman/src/index.ts +++ b/plugins/importer-postman/src/index.ts @@ -47,14 +47,23 @@ export function pluginHookImport( model: 'workspace', id: generateId('workspace'), name: info.name || 'Postman Import', - description: info.description?.content ?? info.description ?? '', + description: info.description?.content ?? info.description, + }; + exportResources.workspaces.push(workspace); + + // Create the base environment + const environment: ExportResources['environments'][0] = { + model: 'environment', + id: generateId('environment'), + name: 'Global Variables', + workspaceId: workspace.id, variables: root.variable?.map((v: any) => ({ name: v.key, value: v.value, })) ?? [], }; - exportResources.workspaces.push(workspace); + exportResources.environments.push(environment); const importItem = (v: Record, folderId: string | null = null) => { if (typeof v.name === 'string' && Array.isArray(v.item)) { @@ -100,6 +109,7 @@ export function pluginHookImport( workspaceId: workspace.id, folderId, name: v.name, + description: v.description || undefined, method: r.method || 'GET', url, urlParameters, @@ -119,7 +129,9 @@ export function pluginHookImport( importItem(item); } - return { resources: convertTemplateSyntax(exportResources) }; + const resources = deleteUndefinedAttrs(convertTemplateSyntax(exportResources)); + + return { resources }; } function convertUrl(url: string | any): Pick { @@ -326,6 +338,20 @@ function convertTemplateSyntax(obj: T): T { } } +function deleteUndefinedAttrs(obj: T): T { + if (Array.isArray(obj) && obj != null) { + return obj.map(deleteUndefinedAttrs) as T; + } else if (typeof obj === 'object' && obj != null) { + return Object.fromEntries( + Object.entries(obj) + .filter(([, v]) => v !== undefined) + .map(([k, v]) => [k, deleteUndefinedAttrs(v)]), + ) as T; + } else { + return obj; + } +} + const idCount: Partial> = {}; function generateId(model: string): string { diff --git a/plugins/importer-postman/tests/fixtures/nested.output.json b/plugins/importer-postman/tests/fixtures/nested.output.json index 9b7cc2c53..9e9bfaab4 100644 --- a/plugins/importer-postman/tests/fixtures/nested.output.json +++ b/plugins/importer-postman/tests/fixtures/nested.output.json @@ -4,12 +4,18 @@ { "model": "workspace", "id": "GENERATE_ID::WORKSPACE_0", - "name": "New Collection", - "description": "", - "variables": [] + "name": "New Collection" + } + ], + "environments": [ + { + "id": "GENERATE_ID::ENVIRONMENT_0", + "model": "environment", + "name": "Global Variables", + "variables": [], + "workspaceId": "GENERATE_ID::WORKSPACE_0" } ], - "environments": [], "httpRequests": [ { "model": "http_request", diff --git a/plugins/importer-postman/tests/fixtures/params.output.json b/plugins/importer-postman/tests/fixtures/params.output.json index 2ad692aeb..1eb16ce33 100644 --- a/plugins/importer-postman/tests/fixtures/params.output.json +++ b/plugins/importer-postman/tests/fixtures/params.output.json @@ -4,8 +4,15 @@ { "model": "workspace", "id": "GENERATE_ID::WORKSPACE_1", - "name": "New Collection", - "description": "", + "name": "New Collection" + } + ], + "environments": [ + { + "id": "GENERATE_ID::ENVIRONMENT_1", + "workspaceId": "GENERATE_ID::WORKSPACE_1", + "model": "environment", + "name": "Global Variables", "variables": [ { "name": "COLLECTION VARIABLE", @@ -14,7 +21,6 @@ ] } ], - "environments": [], "httpRequests": [ { "model": "http_request", diff --git a/plugins/importer-yaak/src/index.ts b/plugins/importer-yaak/src/index.ts index 8e53dd4de..136bc745d 100644 --- a/plugins/importer-yaak/src/index.ts +++ b/plugins/importer-yaak/src/index.ts @@ -1,4 +1,4 @@ -import { Context } from '@yaakapp/api'; +import { Context, Environment } from '@yaakapp/api'; export function pluginHookImport(_ctx: Context, contents: string) { let parsed; @@ -23,6 +23,31 @@ export function pluginHookImport(_ctx: Context, contents: string) { delete parsed.resources['requests']; } + // Migrate v2 to v3 + for (const workspace of parsed.resources.workspaces ?? []) { + if ('variables' in workspace) { + // Create the base environment + const baseEnvironment: Partial = { + id: `GENERATE_ID::base_env_${workspace['id']}`, + name: 'Global Variables', + variables: workspace.variables, + workspaceId: workspace.id, + }; + parsed.resources.environments = parsed.resources.environments ?? []; + parsed.resources.environments.push(baseEnvironment); + + // Delete variables key from workspace + delete workspace.variables; + + // Add environmentId to relevant environments + for (const environment of parsed.resources.environments) { + if (environment.workspaceId === workspace.id && environment.id !== baseEnvironment.id) { + environment.environmentId = baseEnvironment.id; + } + } + } + } + return { resources: parsed.resources }; // Should already be in the correct format } diff --git a/plugins/importer-yaak/tests/index.test.ts b/plugins/importer-yaak/tests/index.test.ts index 0e4187d27..3c47c35a8 100644 --- a/plugins/importer-yaak/tests/index.test.ts +++ b/plugins/importer-yaak/tests/index.test.ts @@ -30,4 +30,46 @@ describe('importer-yaak', () => { }), ); }); + test('converts schema 2 to 3', () => { + const imported = pluginHookImport( + ctx, + JSON.stringify({ + yaakSchema: 2, + resources: { + environments: [{ + id: 'e_1', + workspaceId: 'w_1', + name: 'Production', + variables: [{ name: 'E1', value: 'E1!' }], + }], + workspaces: [{ + id: 'w_1', + variables: [{ name: 'W1', value: 'W1!' }], + }], + }, + }), + ); + + expect(imported).toEqual( + expect.objectContaining({ + resources: { + workspaces: [{ + id: 'w_1', + }], + environments: [{ + id: 'e_1', + environmentId: 'GENERATE_ID::base_env_w_1', + workspaceId: 'w_1', + name: 'Production', + variables: [{ name: 'E1', value: 'E1!' }], + }, { + id: 'GENERATE_ID::base_env_w_1', + workspaceId: 'w_1', + name: 'Global Variables', + variables: [{ name: 'W1', value: 'W1!' }], + }], + }, + }), + ); + }); }); From e213c76870a77e3cf2d5caf6132b7d95677013be Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 14 Jan 2025 10:52:32 -0800 Subject: [PATCH 049/996] More plugins (#4) --- package-lock.json | 23 ++++++---- plugins/template-function-file/package.json | 9 ++++ plugins/template-function-file/src/index.ts | 18 ++++++++ plugins/template-function-prompt/src/index.ts | 1 + .../template-function-request/package.json | 9 ++++ .../template-function-request/src/index.ts | 45 +++++++++++++++++++ .../template-function-response/package.json | 2 +- 7 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 plugins/template-function-file/package.json create mode 100644 plugins/template-function-file/src/index.ts create mode 100755 plugins/template-function-request/package.json create mode 100755 plugins/template-function-request/src/index.ts diff --git a/package-lock.json b/package-lock.json index b3b9a7c2f..4260ddd39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1042,6 +1042,10 @@ "resolved": "plugins/importer-yaak", "link": true }, + "node_modules/@yaakapp/template-function-file": { + "resolved": "plugins/template-function-file", + "link": true + }, "node_modules/@yaakapp/template-function-fs": { "resolved": "plugins/template-function-fs", "link": true @@ -1054,6 +1058,14 @@ "resolved": "plugins/template-function-prompt", "link": true }, + "node_modules/@yaakapp/template-function-request": { + "resolved": "plugins/template-function-request", + "link": true + }, + "node_modules/@yaakapp/template-function-response": { + "resolved": "plugins/template-function-response", + "link": true + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -5810,10 +5822,6 @@ "array-includes": "^3.0.3" } }, - "node_modules/template-function-response": { - "resolved": "plugins/template-function-response", - "link": true - }, "node_modules/through2": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", @@ -6698,8 +6706,7 @@ }, "plugins/template-function-file": { "name": "@yaakapp/template-function-file", - "version": "0.0.1", - "extraneous": true + "version": "0.0.1" }, "plugins/template-function-fs": { "name": "@yaakapp/template-function-fs", @@ -6715,10 +6722,10 @@ }, "plugins/template-function-request": { "name": "@yaakapp/template-function-request", - "version": "0.0.1", - "extraneous": true + "version": "0.0.1" }, "plugins/template-function-response": { + "name": "@yaakapp/template-function-response", "version": "0.0.1", "dependencies": { "@xmldom/xmldom": "^0.8.10", diff --git a/plugins/template-function-file/package.json b/plugins/template-function-file/package.json new file mode 100644 index 000000000..59aea7ab3 --- /dev/null +++ b/plugins/template-function-file/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/template-function-file", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/plugins/template-function-file/src/index.ts b/plugins/template-function-file/src/index.ts new file mode 100644 index 000000000..472c1a0d9 --- /dev/null +++ b/plugins/template-function-file/src/index.ts @@ -0,0 +1,18 @@ +import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; +import fs from 'node:fs'; + +export const plugin: PluginDefinition = { + templateFunctions: [{ + name: 'fs.readFile', + args: [{ title: 'Select File', type: 'file', name: 'path', label: 'File' }], + async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { + if (!args.values.path) return null; + + try { + return fs.promises.readFile(args.values.path, 'utf-8'); + } catch (err) { + return null; + } + }, + }], +}; diff --git a/plugins/template-function-prompt/src/index.ts b/plugins/template-function-prompt/src/index.ts index 957bc8fff..a40ce13ef 100644 --- a/plugins/template-function-prompt/src/index.ts +++ b/plugins/template-function-prompt/src/index.ts @@ -6,6 +6,7 @@ export const plugin: PluginDefinition = { description: 'Prompt the user for input when sending a request', args: [ { type: 'text', name: 'title', label: 'Title' }, + { type: 'text', name: 'label', label: 'Label', optional: true }, { type: 'text', name: 'defaultValue', label: 'Default Value', optional: true }, { type: 'text', name: 'placeholder', label: 'Placeholder', optional: true }, ], diff --git a/plugins/template-function-request/package.json b/plugins/template-function-request/package.json new file mode 100755 index 000000000..a3ebb038d --- /dev/null +++ b/plugins/template-function-request/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/template-function-request", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/plugins/template-function-request/src/index.ts b/plugins/template-function-request/src/index.ts new file mode 100755 index 000000000..0567d5871 --- /dev/null +++ b/plugins/template-function-request/src/index.ts @@ -0,0 +1,45 @@ +import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; + +export const plugin: PluginDefinition = { + templateFunctions: [ + { + name: 'request.body', + args: [{ + name: 'requestId', + label: 'Http Request', + type: 'http_request', + }], + async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { + const httpRequest = await ctx.httpRequest.getById({ id: args.values.requestId ?? 'n/a' }); + if (httpRequest == null) return null; + return String(await ctx.templates.render({ + data: httpRequest.body?.text ?? '', + purpose: args.purpose, + })); + }, + }, + { + name: 'request.header', + args: [ + { + name: 'requestId', + label: 'Http Request', + type: 'http_request', + }, + { + name: 'header', + label: 'Header Name', + type: 'text', + }], + async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise { + const httpRequest = await ctx.httpRequest.getById({ id: args.values.requestId ?? 'n/a' }); + if (httpRequest == null) return null; + const header = httpRequest.headers.find(h => h.name.toLowerCase() === args.values.header?.toLowerCase()); + return String(await ctx.templates.render({ + data: header?.value ?? '', + purpose: args.purpose, + })); + }, + }, + ], +}; diff --git a/plugins/template-function-response/package.json b/plugins/template-function-response/package.json index dfb064aca..7cb3a387d 100644 --- a/plugins/template-function-response/package.json +++ b/plugins/template-function-response/package.json @@ -1,5 +1,5 @@ { - "name": "template-function-response", + "name": "@yaakapp/template-function-response", "private": true, "version": "0.0.1", "scripts": { From ebb7b69dd8d8ad4d167013fa1ac4647d8a0d9929 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 16 Jan 2025 15:28:25 -0800 Subject: [PATCH 050/996] Add auth plugins --- package-lock.json | 231 ++++++++++++++++++++++++++++++- package.json | 2 +- plugins/auth-basic/package.json | 9 ++ plugins/auth-basic/src/index.ts | 28 ++++ plugins/auth-bearer/package.json | 9 ++ plugins/auth-bearer/src/index.ts | 23 +++ 6 files changed, 295 insertions(+), 7 deletions(-) create mode 100644 plugins/auth-basic/package.json create mode 100644 plugins/auth-basic/src/index.ts create mode 100644 plugins/auth-bearer/package.json create mode 100644 plugins/auth-bearer/src/index.ts diff --git a/package-lock.json b/package-lock.json index 4260ddd39..2d35f72d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.2.17" + "@yaakapp/api": "^0.2.26" }, "devDependencies": { "@types/node": "^22.7.4", @@ -855,6 +855,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", + "integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/minimatch": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", @@ -1003,13 +1013,25 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.17.tgz", - "integrity": "sha512-4ldxDxz2x4WCl4LR/D8Z6zyQGuMhBX3c4eMGDqxCjtEd5tXWaKJYQBEdi/Hp2FG0NSPNBEtyVfZd52sGfiqBoA==", + "version": "0.2.26", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.26.tgz", + "integrity": "sha512-l9oBrh4oHJHcrdHaUQivFswoTui/32iWjaSP2SDA9tjBFVsuJAs2iKsKNMvCsBkr9bu1dN/si3wg2HmtwhDDxw==", "dependencies": { "@types/node": "^22.5.4" } }, + "node_modules/@yaakapp/auth-basic": { + "resolved": "plugins/auth-basic", + "link": true + }, + "node_modules/@yaakapp/auth-bearer": { + "resolved": "plugins/auth-bearer", + "link": true + }, + "node_modules/@yaakapp/auth-jwt": { + "resolved": "plugins/auth-jwt", + "link": true + }, "node_modules/@yaakapp/exporter-curl": { "resolved": "plugins/exporter-curl", "link": true @@ -1408,6 +1430,12 @@ "node": ">=8" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -1927,6 +1955,15 @@ "readable-stream": "~1.1.9" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -3704,6 +3741,49 @@ "node": ">=14.0.0" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -3762,6 +3842,48 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, "node_modules/loupe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", @@ -3983,8 +4105,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.7", @@ -5026,6 +5147,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", @@ -6646,6 +6787,32 @@ "node": ">=12" } }, + "plugins/auth-basic": { + "name": "@yaakapp/auth-basic", + "version": "0.0.1" + }, + "plugins/auth-bearer": { + "name": "@yaakapp/auth-bearer", + "version": "0.0.1" + }, + "plugins/auth-digest": { + "name": "@yaakapp/auth-digest", + "version": "0.0.1", + "extraneous": true, + "dependencies": { + "digest-header": "^1.1.0" + } + }, + "plugins/auth-jwt": { + "name": "@yaakapp/auth-jwt", + "version": "0.0.1", + "dependencies": { + "jsonwebtoken": "^9.0.2" + }, + "devDependencies": { + "@types/jsonwebtoken": "^9.0.7" + } + }, "plugins/exporter-curl": { "name": "@yaakapp/exporter-curl", "version": "0.0.1" @@ -6735,6 +6902,58 @@ "devDependencies": { "@types/jsonpath": "^0.2.4" } + }, + "plugins/template-function-response-2": { + "name": "@yaakapp/template-function-response-2", + "version": "0.0.1", + "extraneous": true, + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "jsonpath-plus": "^9.0.0", + "xpath": "^0.0.34" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } + }, + "plugins/template-function-response-3": { + "name": "@yaakapp/template-function-response-3", + "version": "0.0.1", + "extraneous": true, + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "jsonpath-plus": "^9.0.0", + "xpath": "^0.0.34" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } + }, + "plugins/template-function-response-4": { + "name": "@yaakapp/template-function-response-4", + "version": "0.0.1", + "extraneous": true, + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "jsonpath-plus": "^9.0.0", + "xpath": "^0.0.34" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } + }, + "plugins/template-function-response-5": { + "name": "@yaakapp/template-function-response-5", + "version": "0.0.1", + "extraneous": true, + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "jsonpath-plus": "^9.0.0", + "xpath": "^0.0.34" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } } } } diff --git a/package.json b/package.json index abcc0fa73..245529ce3 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.2.17" + "@yaakapp/api": "^0.2.26" } } diff --git a/plugins/auth-basic/package.json b/plugins/auth-basic/package.json new file mode 100644 index 000000000..564447820 --- /dev/null +++ b/plugins/auth-basic/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/auth-basic", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/plugins/auth-basic/src/index.ts b/plugins/auth-basic/src/index.ts new file mode 100644 index 000000000..103a01ff2 --- /dev/null +++ b/plugins/auth-basic/src/index.ts @@ -0,0 +1,28 @@ +import { PluginDefinition } from '@yaakapp/api'; + +export const plugin: PluginDefinition = { + authentication: { + name: 'Basic', + config: [{ + type: 'text', + name: 'username', + label: 'Username', + optional: true, + }, { + type: 'text', + name: 'password', + label: 'Password', + optional: true, + }], + async onApply(_ctx: any, args: any): Promise { + const { username, password } = args.config; + return { + url: args.url, + headers: [{ + name: 'Authorization', + value: 'Basic ' + Buffer.from(`${username}:${password}`).toString('base64'), + }], + }; + }, + }, +}; diff --git a/plugins/auth-bearer/package.json b/plugins/auth-bearer/package.json new file mode 100644 index 000000000..03cf86627 --- /dev/null +++ b/plugins/auth-bearer/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/auth-bearer", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/plugins/auth-bearer/src/index.ts b/plugins/auth-bearer/src/index.ts new file mode 100644 index 000000000..1ed40b89c --- /dev/null +++ b/plugins/auth-bearer/src/index.ts @@ -0,0 +1,23 @@ +import { PluginDefinition } from '@yaakapp/api'; + +export const plugin: PluginDefinition = { + authentication: { + name: 'Bearer', + config: [{ + type: 'text', + name: 'token', + label: 'Token', + optional: true, + }], + async onApply(_ctx: any, args: any): Promise { + const { token } = args.config; + return { + url: args.url, + headers: [{ + name: 'Authorization', + value: `Bearer ${token}`.trim(), + }], + }; + }, + }, +}; From 064416398b8dcd4d740fc0fdb5037b930f3141f3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 17 Jan 2025 08:01:50 -0800 Subject: [PATCH 051/996] JWT auth plugin and updates --- package-lock.json | 8 ++-- package.json | 2 +- plugins/auth-basic/src/index.ts | 5 ++- plugins/auth-bearer/src/index.ts | 5 ++- plugins/auth-jwt/package.json | 15 ++++++++ plugins/auth-jwt/src/index.ts | 65 ++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 plugins/auth-jwt/package.json create mode 100644 plugins/auth-jwt/src/index.ts diff --git a/package-lock.json b/package-lock.json index 2d35f72d3..639002542 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.2.26" + "@yaakapp/api": "^0.2.27" }, "devDependencies": { "@types/node": "^22.7.4", @@ -1013,9 +1013,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.26", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.26.tgz", - "integrity": "sha512-l9oBrh4oHJHcrdHaUQivFswoTui/32iWjaSP2SDA9tjBFVsuJAs2iKsKNMvCsBkr9bu1dN/si3wg2HmtwhDDxw==", + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.27.tgz", + "integrity": "sha512-OkgABeXDxlg3Vx3HbpkIFvAaMTxfqcLQx4X7Tm5/24eZOzbp/n2dtRXRBUcd4w7hI/NjQUetGxjPBTxlJDsQxQ==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/package.json b/package.json index 245529ce3..a9989426c 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.2.26" + "@yaakapp/api": "^0.2.27" } } diff --git a/plugins/auth-basic/src/index.ts b/plugins/auth-basic/src/index.ts index 103a01ff2..7661cd4c0 100644 --- a/plugins/auth-basic/src/index.ts +++ b/plugins/auth-basic/src/index.ts @@ -2,7 +2,9 @@ import { PluginDefinition } from '@yaakapp/api'; export const plugin: PluginDefinition = { authentication: { - name: 'Basic', + name: 'basic', + label: 'Basic Auth', + shortLabel: 'Basic', config: [{ type: 'text', name: 'username', @@ -13,6 +15,7 @@ export const plugin: PluginDefinition = { name: 'password', label: 'Password', optional: true, + password: true, }], async onApply(_ctx: any, args: any): Promise { const { username, password } = args.config; diff --git a/plugins/auth-bearer/src/index.ts b/plugins/auth-bearer/src/index.ts index 1ed40b89c..5b6783d84 100644 --- a/plugins/auth-bearer/src/index.ts +++ b/plugins/auth-bearer/src/index.ts @@ -2,12 +2,15 @@ import { PluginDefinition } from '@yaakapp/api'; export const plugin: PluginDefinition = { authentication: { - name: 'Bearer', + name: 'bearer', + label: 'Bearer Token', + shortLabel: 'Bearer', config: [{ type: 'text', name: 'token', label: 'Token', optional: true, + password: true, }], async onApply(_ctx: any, args: any): Promise { const { token } = args.config; diff --git a/plugins/auth-jwt/package.json b/plugins/auth-jwt/package.json new file mode 100644 index 000000000..777f9d9bc --- /dev/null +++ b/plugins/auth-jwt/package.json @@ -0,0 +1,15 @@ +{ + "name": "@yaakapp/auth-jwt", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + }, + "dependencies": { + "jsonwebtoken": "^9.0.2" + }, + "devDependencies": { + "@types/jsonwebtoken": "^9.0.7" + } +} diff --git a/plugins/auth-jwt/src/index.ts b/plugins/auth-jwt/src/index.ts new file mode 100644 index 000000000..ecad48e99 --- /dev/null +++ b/plugins/auth-jwt/src/index.ts @@ -0,0 +1,65 @@ +import { PluginDefinition } from '@yaakapp/api'; +import jwt from 'jsonwebtoken'; + +const algorithms = [ + 'HS256', + 'HS384', + 'HS512', + 'RS256', + 'RS384', + 'RS512', + 'PS256', + 'PS384', + 'PS512', + 'ES256', + 'ES384', + 'ES512', +]; + +const defaultAlgorithm = algorithms[0]; + +export const plugin: PluginDefinition = { + authentication: { + name: 'jwt', + label: 'JWT Bearer', + shortLabel: 'JWT', + config: [ + { + type: 'select', + name: 'algorithm', + label: 'Algorithm', + defaultValue: defaultAlgorithm, + options: algorithms.map(value => ({ name: value, value })), + }, + { + type: 'text', + name: 'secret', + label: 'Secret', + optional: true, + }, + { + type: 'checkbox', + name: 'secretBase64', + label: 'Secret Base64 Encoded', + }, + { + type: 'editor', + name: 'payload', + label: 'Payload', + language: 'json', + optional: true, + }, + ], + async onApply(_ctx, args) { + const { algorithm, secret: _secret, secretBase64, payload } = args.config; + const secret = secretBase64 ? Buffer.from(`${_secret}`, 'base64') : `${_secret}`; + const token = jwt.sign(`${payload}`, secret, { algorithm: algorithm as any }); + return { + url: args.url, + headers: [{ name: 'Authorization', value: `Bearer ${token}` }], + }; + } + , + }, + } +; From 16af8bf0081d2cdbcdc8339c888a0cecd27c05ff Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 17 Jan 2025 14:38:17 -0800 Subject: [PATCH 052/996] JWT plugin --- package-lock.json | 8 ++++---- package.json | 2 +- plugins/auth-basic/src/index.ts | 11 +++-------- plugins/auth-bearer/src/index.ts | 11 +++-------- plugins/auth-jwt/src/index.ts | 13 ++++++------- plugins/template-function-response/src/index.ts | 10 +++++----- 6 files changed, 22 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 639002542..910150bbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.2.27" + "@yaakapp/api": "^0.2.29" }, "devDependencies": { "@types/node": "^22.7.4", @@ -1013,9 +1013,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.27", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.27.tgz", - "integrity": "sha512-OkgABeXDxlg3Vx3HbpkIFvAaMTxfqcLQx4X7Tm5/24eZOzbp/n2dtRXRBUcd4w7hI/NjQUetGxjPBTxlJDsQxQ==", + "version": "0.2.29", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.29.tgz", + "integrity": "sha512-RuyWRUGhYIQjFmaZTYuAekSkidl0b9rWcTV1l+Hs5Pw+LUv8+euedAvNodEJgxAgy42btUns7QUmdM5YNvgoug==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/package.json b/package.json index a9989426c..9e4eced14 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.2.27" + "@yaakapp/api": "^0.2.29" } } diff --git a/plugins/auth-basic/src/index.ts b/plugins/auth-basic/src/index.ts index 7661cd4c0..342b3cf12 100644 --- a/plugins/auth-basic/src/index.ts +++ b/plugins/auth-basic/src/index.ts @@ -17,15 +17,10 @@ export const plugin: PluginDefinition = { optional: true, password: true, }], - async onApply(_ctx: any, args: any): Promise { + async onApply(_ctx, args) { const { username, password } = args.config; - return { - url: args.url, - headers: [{ - name: 'Authorization', - value: 'Basic ' + Buffer.from(`${username}:${password}`).toString('base64'), - }], - }; + const value = 'Basic ' + Buffer.from(`${username}:${password}`).toString('base64'); + return { setHeaders: [{ name: 'Authorization', value }] }; }, }, }; diff --git a/plugins/auth-bearer/src/index.ts b/plugins/auth-bearer/src/index.ts index 5b6783d84..a08a5dd36 100644 --- a/plugins/auth-bearer/src/index.ts +++ b/plugins/auth-bearer/src/index.ts @@ -12,15 +12,10 @@ export const plugin: PluginDefinition = { optional: true, password: true, }], - async onApply(_ctx: any, args: any): Promise { + async onApply(_ctx, args) { const { token } = args.config; - return { - url: args.url, - headers: [{ - name: 'Authorization', - value: `Bearer ${token}`.trim(), - }], - }; + const value = `Bearer ${token}`.trim(); + return { setHeaders: [{ name: 'Authorization', value }] }; }, }, }; diff --git a/plugins/auth-jwt/src/index.ts b/plugins/auth-jwt/src/index.ts index ecad48e99..b5e2309ad 100644 --- a/plugins/auth-jwt/src/index.ts +++ b/plugins/auth-jwt/src/index.ts @@ -14,7 +14,8 @@ const algorithms = [ 'ES256', 'ES384', 'ES512', -]; + 'none', +] as const; const defaultAlgorithm = algorithms[0]; @@ -29,7 +30,7 @@ export const plugin: PluginDefinition = { name: 'algorithm', label: 'Algorithm', defaultValue: defaultAlgorithm, - options: algorithms.map(value => ({ name: value, value })), + options: algorithms.map(value => ({ name: value === 'none' ? 'None' : value, value })), }, { type: 'text', @@ -53,11 +54,9 @@ export const plugin: PluginDefinition = { async onApply(_ctx, args) { const { algorithm, secret: _secret, secretBase64, payload } = args.config; const secret = secretBase64 ? Buffer.from(`${_secret}`, 'base64') : `${_secret}`; - const token = jwt.sign(`${payload}`, secret, { algorithm: algorithm as any }); - return { - url: args.url, - headers: [{ name: 'Authorization', value: `Bearer ${token}` }], - }; + const token = secret ? jwt.sign(`${payload}`, secret, { algorithm: algorithm as any }) : jwt.sign(`${payload}`, null); + const value = `Bearer ${token}`; + return { setHeaders: [{ name: 'Authorization', value }] }; } , }, diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts index 90bb65253..15a67a003 100644 --- a/plugins/template-function-response/src/index.ts +++ b/plugins/template-function-response/src/index.ts @@ -2,27 +2,27 @@ import { DOMParser } from '@xmldom/xmldom'; import { CallTemplateFunctionArgs, Context, + FormInput, HttpResponse, PluginDefinition, RenderPurpose, - TemplateFunctionArg, } from '@yaakapp/api'; import { JSONPath } from 'jsonpath-plus'; import { readFileSync } from 'node:fs'; import xpath from 'xpath'; -const behaviorArg: TemplateFunctionArg = { +const behaviorArg: FormInput = { type: 'select', name: 'behavior', label: 'Sending Behavior', defaultValue: 'smart', options: [ - { label: 'When no responses', value: 'smart' }, - { label: 'Always', value: 'always' }, + { name: 'When no responses', value: 'smart' }, + { name: 'Always', value: 'always' }, ], }; -const requestArg: TemplateFunctionArg = +const requestArg: FormInput = { type: 'http_request', name: 'request', From 0491bed46df6e4be05dd2c4c24856a5bd7981632 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 17 Jan 2025 15:10:02 -0800 Subject: [PATCH 053/996] A few tweaks --- package-lock.json | 8 ++++---- package.json | 2 +- plugins/auth-jwt/src/index.ts | 10 ++++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 910150bbc..e01ed848d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.2.29" + "@yaakapp/api": "^0.3.0" }, "devDependencies": { "@types/node": "^22.7.4", @@ -1013,9 +1013,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.2.29", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.2.29.tgz", - "integrity": "sha512-RuyWRUGhYIQjFmaZTYuAekSkidl0b9rWcTV1l+Hs5Pw+LUv8+euedAvNodEJgxAgy42btUns7QUmdM5YNvgoug==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.3.0.tgz", + "integrity": "sha512-A2msKEiqVIOdqn2q9oVXT69aJ7EwrbwNZ6gdrvqTqeTERLddRtO0OKj6wYUUpiqbGr1QY8Byu4BzHclp/aYHWw==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/package.json b/package.json index 9e4eced14..f73d48a62 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.2.29" + "@yaakapp/api": "^0.3.0" } } diff --git a/plugins/auth-jwt/src/index.ts b/plugins/auth-jwt/src/index.ts index b5e2309ad..309c68090 100644 --- a/plugins/auth-jwt/src/index.ts +++ b/plugins/auth-jwt/src/index.ts @@ -29,32 +29,34 @@ export const plugin: PluginDefinition = { type: 'select', name: 'algorithm', label: 'Algorithm', + hideLabel: true, defaultValue: defaultAlgorithm, options: algorithms.map(value => ({ name: value === 'none' ? 'None' : value, value })), }, { type: 'text', name: 'secret', - label: 'Secret', + label: 'Secret or Private Key', optional: true, }, { type: 'checkbox', name: 'secretBase64', - label: 'Secret Base64 Encoded', + label: 'Secret is base64 encoded', }, { type: 'editor', name: 'payload', label: 'Payload', language: 'json', - optional: true, + defaultValue: '{\n "foo": "bar"\n}', + placeholder: '{ }', }, ], async onApply(_ctx, args) { const { algorithm, secret: _secret, secretBase64, payload } = args.config; const secret = secretBase64 ? Buffer.from(`${_secret}`, 'base64') : `${_secret}`; - const token = secret ? jwt.sign(`${payload}`, secret, { algorithm: algorithm as any }) : jwt.sign(`${payload}`, null); + const token = jwt.sign(`${payload}`, secret, { algorithm: algorithm as any }); const value = `Bearer ${token}`; return { setHeaders: [{ name: 'Authorization', value }] }; } From 26cce077bbf06740e49ee86eadae96f88f2bf0c3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 17 Jan 2025 15:21:41 -0800 Subject: [PATCH 054/996] Secret key to editor type --- package-lock.json | 8 ++++---- package.json | 2 +- plugins/auth-jwt/src/index.ts | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index e01ed848d..19c020c76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.3.0" + "@yaakapp/api": "^0.3.2" }, "devDependencies": { "@types/node": "^22.7.4", @@ -1013,9 +1013,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.3.0.tgz", - "integrity": "sha512-A2msKEiqVIOdqn2q9oVXT69aJ7EwrbwNZ6gdrvqTqeTERLddRtO0OKj6wYUUpiqbGr1QY8Byu4BzHclp/aYHWw==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.3.2.tgz", + "integrity": "sha512-NiYQiVClAGfWelg5hwPhjRmYhC8K5KUtJS4tXdQpq573lUDQ7Dql7qsgnRwMUZ8gaiiDN7OXuphHXopndHLA+A==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/package.json b/package.json index f73d48a62..2f214778c 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.3.0" + "@yaakapp/api": "^0.3.2" } } diff --git a/plugins/auth-jwt/src/index.ts b/plugins/auth-jwt/src/index.ts index 309c68090..9edc25215 100644 --- a/plugins/auth-jwt/src/index.ts +++ b/plugins/auth-jwt/src/index.ts @@ -34,10 +34,11 @@ export const plugin: PluginDefinition = { options: algorithms.map(value => ({ name: value === 'none' ? 'None' : value, value })), }, { - type: 'text', + type: 'editor', name: 'secret', label: 'Secret or Private Key', optional: true, + hideGutter: true, }, { type: 'checkbox', From d142966d0ccadbbd43816fe35039f0e5c8685c48 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 20 Jan 2025 13:07:04 -0800 Subject: [PATCH 055/996] Update plugins --- package-lock.json | 1090 +++++++++++------ package.json | 2 +- plugins/exporter-curl/src/index.ts | 6 +- plugins/exporter-curl/tests/index.test.ts | 35 +- plugins/filter-jsonpath/src/index.ts | 18 +- plugins/filter-xpath/src/index.ts | 32 +- plugins/importer-curl/src/index.ts | 14 +- plugins/importer-curl/tests/index.test.ts | 52 +- plugins/importer-insomnia/src/index.ts | 14 +- plugins/importer-insomnia/tests/index.test.ts | 7 +- plugins/importer-openapi/src/index.ts | 20 +- plugins/importer-openapi/tests/index.test.ts | 11 +- plugins/importer-postman/src/index.ts | 14 +- plugins/importer-postman/tests/index.test.ts | 7 +- plugins/importer-yaak/src/index.ts | 14 +- plugins/importer-yaak/tests/index.test.ts | 17 +- 16 files changed, 852 insertions(+), 501 deletions(-) diff --git a/package-lock.json b/package-lock.json index 19c020c76..84eb4190f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.3.2" + "@yaakapp/api": "^0.3.4" }, "devDependencies": { "@types/node": "^22.7.4", @@ -33,13 +33,14 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -47,99 +48,15 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@changesets/types": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@changesets/types/-/types-0.4.0.tgz", @@ -1013,9 +930,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.3.2.tgz", - "integrity": "sha512-NiYQiVClAGfWelg5hwPhjRmYhC8K5KUtJS4tXdQpq573lUDQ7Dql7qsgnRwMUZ8gaiiDN7OXuphHXopndHLA+A==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.3.4.tgz", + "integrity": "sha512-Yx0wigj+Re8cnYM1PJijTisRIL8jFeK50nJ66Hiv/OxPhX2QjqDWmOXGZ3TsRU9NB41JM74O1OfafRMhfeSUMw==", "dependencies": { "@types/node": "^22.5.4" } @@ -1210,14 +1127,14 @@ } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -1281,20 +1198,19 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -1467,17 +1383,47 @@ } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -1750,15 +1696,15 @@ } }, "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -1768,31 +1714,31 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -1880,7 +1826,8 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/define-data-property": { "version": "1.1.4", @@ -1945,6 +1892,21 @@ "node": ">=4" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer2": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", @@ -1981,58 +1943,63 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" }, "engines": { "node": ">= 0.4" @@ -2042,14 +2009,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -2065,9 +2029,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", "dependencies": { @@ -2078,30 +2042,31 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -2163,21 +2128,12 @@ "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/escodegen": { "version": "1.14.3", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^4.2.0", @@ -2200,6 +2156,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -2226,6 +2183,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2244,6 +2202,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2594,7 +2553,8 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-safe-stringify": { "version": "2.1.1", @@ -2724,16 +2684,18 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -2771,17 +2733,22 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -2790,6 +2757,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", @@ -2803,15 +2784,15 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -2933,13 +2914,13 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2972,11 +2953,14 @@ } }, "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3005,11 +2989,14 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -3018,9 +3005,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { @@ -3207,15 +3194,15 @@ "license": "ISC" }, "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -3235,14 +3222,15 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -3258,28 +3246,50 @@ "dev": true, "license": "MIT" }, + "node_modules/is-async-function": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.0.tgz", + "integrity": "sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", + "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -3309,9 +3319,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { @@ -3338,12 +3348,14 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -3354,13 +3366,14 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -3406,6 +3419,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -3415,6 +3444,25 @@ "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -3428,10 +3476,10 @@ "node": ">=0.10.0" } }, - "node_modules/is-negative-zero": { + "node_modules/is-map": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "license": "MIT", "engines": { @@ -3452,13 +3500,14 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -3491,14 +3540,16 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -3507,14 +3558,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -3536,13 +3600,14 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -3552,13 +3617,15 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -3568,14 +3635,27 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3584,13 +3664,33 @@ } }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", + "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3717,6 +3817,7 @@ "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", "dev": true, + "license": "MIT", "dependencies": { "esprima": "1.2.2", "static-eval": "2.0.2", @@ -3799,6 +3900,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -3938,6 +4040,16 @@ "node": ">=0.10.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/meow": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", @@ -4439,9 +4551,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, "license": "MIT", "engines": { @@ -4475,15 +4587,17 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -4576,6 +4690,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", @@ -4588,6 +4703,24 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -4977,6 +5110,29 @@ "node": ">=8" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/reftools": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", @@ -5001,16 +5157,18 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -5058,19 +5216,22 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5129,15 +5290,16 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -5167,6 +5329,23 @@ ], "license": "MIT" }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", @@ -5178,15 +5357,15 @@ } }, "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -5247,6 +5426,21 @@ "node": ">= 0.4" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -5371,16 +5565,73 @@ "license": "MIT" }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -5573,6 +5824,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" @@ -5640,9 +5892,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", - "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", "dev": true, "license": "CC0-1.0" }, @@ -5730,6 +5982,7 @@ "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", "dev": true, + "license": "MIT", "dependencies": { "escodegen": "^1.8.1" } @@ -5803,16 +6056,19 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5822,16 +6078,20 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6103,6 +6363,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "~1.1.2" }, @@ -6124,32 +6385,32 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -6159,18 +6420,19 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -6180,18 +6442,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -6215,16 +6477,19 @@ } }, "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6234,7 +6499,8 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/undici-types": { "version": "6.19.8", @@ -6590,33 +6856,84 @@ } }, "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "for-each": "^0.3.3", - "gopd": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -6647,6 +6964,7 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } diff --git a/package.json b/package.json index 2f214778c..cf4190652 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.3.2" + "@yaakapp/api": "^0.3.4" } } diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts index c4f06a026..fd90e7573 100644 --- a/plugins/exporter-curl/src/index.ts +++ b/plugins/exporter-curl/src/index.ts @@ -1,4 +1,4 @@ -import { Context, HttpRequest, PluginDefinition } from '@yaakapp/api'; +import { HttpRequest, PluginDefinition } from '@yaakapp/api'; const NEWLINE = '\\\n '; @@ -9,14 +9,14 @@ export const plugin: PluginDefinition = { icon: 'copy', async onSelect(ctx, args) { const rendered_request = await ctx.httpRequest.render({ httpRequest: args.httpRequest, purpose: 'preview' }); - const data = await pluginHookExport(ctx, rendered_request); + const data = await convertToCurl(rendered_request); ctx.clipboard.copyText(data); ctx.toast.show({ message: 'Curl copied to clipboard', icon: 'copy' }); }, }], }; -export async function pluginHookExport(_ctx: Context, request: Partial) { +export async function convertToCurl(request: Partial) { const xs = ['curl']; // Add method and URL all on first line diff --git a/plugins/exporter-curl/tests/index.test.ts b/plugins/exporter-curl/tests/index.test.ts index 0b09e8608..0f633a7bc 100644 --- a/plugins/exporter-curl/tests/index.test.ts +++ b/plugins/exporter-curl/tests/index.test.ts @@ -1,13 +1,10 @@ import { describe, expect, test } from 'vitest'; -import { Context } from '@yaakapp/api'; -import { pluginHookExport } from '../src'; - -const ctx = {} as Context; +import { convertToCurl } from '../src'; describe('exporter-curl', () => { test('Exports GET with params', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', urlParameters: [ { name: 'a', value: 'aaa' }, @@ -21,7 +18,7 @@ describe('exporter-curl', () => { }); test('Exports POST with url form data', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', method: 'POST', bodyType: 'application/x-www-form-urlencoded', @@ -40,12 +37,12 @@ describe('exporter-curl', () => { test('Exports POST with GraphQL data', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', method: 'POST', bodyType: 'graphql', body: { - query : '{foo,bar}', + query: '{foo,bar}', variables: '{"a": "aaa", "b": "bbb"}', }, }), @@ -56,12 +53,12 @@ describe('exporter-curl', () => { test('Exports POST with GraphQL data no variables', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', method: 'POST', bodyType: 'graphql', body: { - query : '{foo,bar}', + query: '{foo,bar}', }, }), ).toEqual( @@ -71,7 +68,7 @@ describe('exporter-curl', () => { test('Exports PUT with multipart form', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', method: 'PUT', bodyType: 'multipart/form-data', @@ -96,7 +93,7 @@ describe('exporter-curl', () => { test('Exports JSON body', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', method: 'POST', bodyType: 'application/json', @@ -116,7 +113,7 @@ describe('exporter-curl', () => { test('Exports multi-line JSON body', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', method: 'POST', bodyType: 'application/json', @@ -136,7 +133,7 @@ describe('exporter-curl', () => { test('Exports headers', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ headers: [ { name: 'a', value: 'aaa' }, { name: 'b', value: 'bbb', enabled: true }, @@ -148,7 +145,7 @@ describe('exporter-curl', () => { test('Basic auth', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', authenticationType: 'basic', authentication: { @@ -161,7 +158,7 @@ describe('exporter-curl', () => { test('Broken basic auth', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', authenticationType: 'basic', authentication: {}, @@ -171,7 +168,7 @@ describe('exporter-curl', () => { test('Digest auth', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', authenticationType: 'digest', authentication: { @@ -184,7 +181,7 @@ describe('exporter-curl', () => { test('Bearer auth', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', authenticationType: 'bearer', authentication: { @@ -196,7 +193,7 @@ describe('exporter-curl', () => { test('Broken bearer auth', async () => { expect( - await pluginHookExport(ctx, { + await convertToCurl({ url: 'https://yaak.app', authenticationType: 'bearer', authentication: { diff --git a/plugins/filter-jsonpath/src/index.ts b/plugins/filter-jsonpath/src/index.ts index 2d2e71f57..a4539e616 100644 --- a/plugins/filter-jsonpath/src/index.ts +++ b/plugins/filter-jsonpath/src/index.ts @@ -1,8 +1,14 @@ -import { Context } from '@yaakapp/api'; +import { PluginDefinition } from '@yaakapp/api'; import { JSONPath } from 'jsonpath-plus'; -export function pluginHookResponseFilter(_ctx: Context, args: { filter: string; body: string }) { - const parsed = JSON.parse(args.body); - const filtered = JSONPath({ path: args.filter, json: parsed }); - return JSON.stringify(filtered, null, 2); -} +export const plugin: PluginDefinition = { + filter: { + name: 'JSONPath', + description: 'Filter JSONPath', + onFilter(_ctx, args) { + const parsed = JSON.parse(args.payload); + const filtered = JSONPath({ path: args.filter, json: parsed }); + return { filtered: JSON.stringify(filtered, null, 2) }; + }, + }, +}; diff --git a/plugins/filter-xpath/src/index.ts b/plugins/filter-xpath/src/index.ts index bd7f61c64..4a0106572 100644 --- a/plugins/filter-xpath/src/index.ts +++ b/plugins/filter-xpath/src/index.ts @@ -1,17 +1,21 @@ import { DOMParser } from '@xmldom/xmldom'; -import { Context } from '@yaakapp/api'; +import { PluginDefinition } from '@yaakapp/api'; import xpath from 'xpath'; -export function pluginHookResponseFilter( - _ctx: Context, - { filter, body }: { filter: string; body: string }, -) { - const doc = new DOMParser().parseFromString(body, 'text/xml'); - const result = xpath.select(filter, doc, false); - if (Array.isArray(result)) { - return result.map(r => String(r)).join('\n'); - } else { - // Not sure what cases this happens in (?) - return String(result); - } -} +export const plugin: PluginDefinition = { + filter: { + name: 'XPath', + description: 'Filter XPath', + onFilter(_ctx, args) { + const doc = new DOMParser().parseFromString(args.payload, 'text/xml'); + const result = xpath.select(args.filter, doc, false); + + if (Array.isArray(result)) { + return { filtered: result.map(r => String(r)).join('\n') }; + } else { + // Not sure what cases this happens in (?) + return { filtered: String(result) }; + } + }, + }, +}; diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts index db3e77ce4..95a2b645e 100644 --- a/plugins/importer-curl/src/index.ts +++ b/plugins/importer-curl/src/index.ts @@ -1,4 +1,4 @@ -import { Context, Environment, Folder, HttpRequest, HttpUrlParameter, Workspace } from '@yaakapp/api'; +import { Context, Environment, Folder, HttpRequest, HttpUrlParameter, PluginDefinition, Workspace } from '@yaakapp/api'; import { ControlOperator, parse, ParseEntry } from 'shell-quote'; type AtLeast = Partial & Pick; @@ -35,7 +35,17 @@ type FlagValue = string | boolean; type FlagsByName = Record; -export function pluginHookImport(_ctx: Context, rawData: string) { +export const plugin: PluginDefinition = { + importer: { + name: 'cURL', + description: 'Import cURL commands', + onImport(_ctx: Context, args: { text: string }) { + return convertCurl(args.text) as any; + }, + }, +}; + +export function convertCurl(rawData: string) { if (!rawData.match(/^\s*curl /)) { return null; } diff --git a/plugins/importer-curl/tests/index.test.ts b/plugins/importer-curl/tests/index.test.ts index 862faa6bc..81669fd27 100644 --- a/plugins/importer-curl/tests/index.test.ts +++ b/plugins/importer-curl/tests/index.test.ts @@ -1,12 +1,10 @@ -import { Context, HttpRequest, Workspace } from '@yaakapp/api'; +import { HttpRequest, Workspace } from '@yaakapp/api'; import { describe, expect, test } from 'vitest'; -import { pluginHookImport } from '../src'; - -const ctx = {} as Context; +import { convertCurl } from '../src'; describe('importer-curl', () => { test('Imports basic GET', () => { - expect(pluginHookImport(ctx, 'curl https://yaak.app')).toEqual({ + expect(convertCurl('curl https://yaak.app')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -19,7 +17,7 @@ describe('importer-curl', () => { }); test('Explicit URL', () => { - expect(pluginHookImport(ctx, 'curl --url https://yaak.app')).toEqual({ + expect(convertCurl('curl --url https://yaak.app')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -32,7 +30,7 @@ describe('importer-curl', () => { }); test('Missing URL', () => { - expect(pluginHookImport(ctx, 'curl -X POST')).toEqual({ + expect(convertCurl('curl -X POST')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -45,7 +43,7 @@ describe('importer-curl', () => { }); test('URL between', () => { - expect(pluginHookImport(ctx, 'curl -v https://yaak.app -X POST')).toEqual({ + expect(convertCurl('curl -v https://yaak.app -X POST')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -59,7 +57,7 @@ describe('importer-curl', () => { }); test('Random flags', () => { - expect(pluginHookImport(ctx, 'curl --random -Z -Y -S --foo https://yaak.app')).toEqual({ + expect(convertCurl('curl --random -Z -Y -S --foo https://yaak.app')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -72,7 +70,7 @@ describe('importer-curl', () => { }); test('Imports --request method', () => { - expect(pluginHookImport(ctx, 'curl --request POST https://yaak.app')).toEqual({ + expect(convertCurl('curl --request POST https://yaak.app')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -86,7 +84,7 @@ describe('importer-curl', () => { }); test('Imports -XPOST method', () => { - expect(pluginHookImport(ctx, 'curl -XPOST --request POST https://yaak.app')).toEqual({ + expect(convertCurl('curl -XPOST --request POST https://yaak.app')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -101,10 +99,7 @@ describe('importer-curl', () => { test('Imports multiple requests', () => { expect( - pluginHookImport( - ctx, - 'curl \\\n https://yaak.app\necho "foo"\ncurl example.com;curl foo.com', - ), + convertCurl('curl \\\n https://yaak.app\necho "foo"\ncurl example.com;curl foo.com'), ).toEqual({ resources: { workspaces: [baseWorkspace()], @@ -119,7 +114,7 @@ describe('importer-curl', () => { test('Imports form data', () => { expect( - pluginHookImport(ctx, 'curl -X POST -F "a=aaa" -F b=bbb" -F f=@filepath https://yaak.app'), + convertCurl('curl -X POST -F "a=aaa" -F b=bbb" -F f=@filepath https://yaak.app'), ).toEqual({ resources: { workspaces: [baseWorkspace()], @@ -149,7 +144,7 @@ describe('importer-curl', () => { }); test('Imports data params as form url-encoded', () => { - expect(pluginHookImport(ctx, 'curl -d a -d b -d c=ccc https://yaak.app')).toEqual({ + expect(convertCurl('curl -d a -d b -d c=ccc https://yaak.app')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -179,7 +174,7 @@ describe('importer-curl', () => { test('Imports data params as text', () => { expect( - pluginHookImport(ctx, 'curl -H Content-Type:text/plain -d a -d b -d c=ccc https://yaak.app'), + convertCurl('curl -H Content-Type:text/plain -d a -d b -d c=ccc https://yaak.app'), ).toEqual({ resources: { workspaces: [baseWorkspace()], @@ -198,7 +193,7 @@ describe('importer-curl', () => { test('Imports post data into URL', () => { expect( - pluginHookImport(ctx, 'curl -G https://api.stripe.com/v1/payment_links -d limit=3'), + convertCurl('curl -G https://api.stripe.com/v1/payment_links -d limit=3'), ).toEqual({ resources: { workspaces: [baseWorkspace()], @@ -210,7 +205,7 @@ describe('importer-curl', () => { enabled: true, name: 'limit', value: '3', - }] + }], }), ], }, @@ -219,10 +214,7 @@ describe('importer-curl', () => { test('Imports multi-line JSON', () => { expect( - pluginHookImport( - ctx, - `curl -H Content-Type:application/json -d $'{\n "foo":"bar"\n}' https://yaak.app`, - ), + convertCurl(`curl -H Content-Type:application/json -d $'{\n "foo":"bar"\n}' https://yaak.app`), ).toEqual({ resources: { workspaces: [baseWorkspace()], @@ -241,7 +233,7 @@ describe('importer-curl', () => { test('Imports multiple headers', () => { expect( - pluginHookImport(ctx, 'curl -H Foo:bar --header Name -H AAA:bbb -H :ccc https://yaak.app'), + convertCurl('curl -H Foo:bar --header Name -H AAA:bbb -H :ccc https://yaak.app'), ).toEqual({ resources: { workspaces: [baseWorkspace()], @@ -261,7 +253,7 @@ describe('importer-curl', () => { }); test('Imports basic auth', () => { - expect(pluginHookImport(ctx, 'curl --user user:pass https://yaak.app')).toEqual({ + expect(convertCurl('curl --user user:pass https://yaak.app')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -279,7 +271,7 @@ describe('importer-curl', () => { }); test('Imports digest auth', () => { - expect(pluginHookImport(ctx, 'curl --digest --user user:pass https://yaak.app')).toEqual({ + expect(convertCurl('curl --digest --user user:pass https://yaak.app')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -297,7 +289,7 @@ describe('importer-curl', () => { }); test('Imports cookie as header', () => { - expect(pluginHookImport(ctx, 'curl --cookie "foo=bar" https://yaak.app')).toEqual({ + expect(convertCurl('curl --cookie "foo=bar" https://yaak.app')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -311,7 +303,7 @@ describe('importer-curl', () => { }); test('Imports query params', () => { - expect(pluginHookImport(ctx, 'curl "https://yaak.app" --url-query foo=bar --url-query baz=qux')).toEqual({ + expect(convertCurl('curl "https://yaak.app" --url-query foo=bar --url-query baz=qux')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ @@ -328,7 +320,7 @@ describe('importer-curl', () => { }); test('Imports query params from the URL', () => { - expect(pluginHookImport(ctx, 'curl "https://yaak.app?foo=bar&baz=a%20a"')).toEqual({ + expect(convertCurl('curl "https://yaak.app?foo=bar&baz=a%20a"')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ diff --git a/plugins/importer-insomnia/src/index.ts b/plugins/importer-insomnia/src/index.ts index 12d53c471..d4e04b0a7 100644 --- a/plugins/importer-insomnia/src/index.ts +++ b/plugins/importer-insomnia/src/index.ts @@ -1,4 +1,4 @@ -import { Context, Environment, Folder, GrpcRequest, HttpRequest, Workspace } from '@yaakapp/api'; +import { Context, Environment, Folder, GrpcRequest, HttpRequest, PluginDefinition, Workspace } from '@yaakapp/api'; import YAML from 'yaml'; type AtLeast = Partial & Pick; @@ -11,7 +11,17 @@ export interface ExportResources { folders: AtLeast[]; } -export function pluginHookImport(ctx: Context, contents: string) { +export const plugin: PluginDefinition = { + importer: { + name: 'Insomnia', + description: 'Import Insomnia workspaces', + onImport(_ctx: Context, args: { text: string }) { + return convertInsomnia(args.text) as any; + }, + }, +}; + +export function convertInsomnia(contents: string) { let parsed: any; try { diff --git a/plugins/importer-insomnia/tests/index.test.ts b/plugins/importer-insomnia/tests/index.test.ts index fe073717b..4fb3ecc41 100644 --- a/plugins/importer-insomnia/tests/index.test.ts +++ b/plugins/importer-insomnia/tests/index.test.ts @@ -1,10 +1,7 @@ -import { Context } from '@yaakapp/api'; import * as fs from 'node:fs'; import * as path from 'node:path'; import { describe, expect, test } from 'vitest'; -import { pluginHookImport } from '../src'; - -const ctx = {} as Context; +import { convertInsomnia } from '../src'; describe('importer-yaak', () => { const p = path.join(__dirname, 'fixtures'); @@ -18,7 +15,7 @@ describe('importer-yaak', () => { test('Imports ' + fixture, () => { const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); const expected = fs.readFileSync(path.join(p, fixture.replace('.input', '.output')), 'utf-8'); - const result = pluginHookImport(ctx, contents); + const result = convertInsomnia(contents); // console.log(JSON.stringify(result, null, 2)) expect(result).toEqual(JSON.parse(expected)); }); diff --git a/plugins/importer-openapi/src/index.ts b/plugins/importer-openapi/src/index.ts index 87b8a1178..2080dda4d 100644 --- a/plugins/importer-openapi/src/index.ts +++ b/plugins/importer-openapi/src/index.ts @@ -1,7 +1,6 @@ -import { Context } from '@yaakapp/api'; +import { Context, Environment, Folder, HttpRequest, PluginDefinition, Workspace } from '@yaakapp/api'; import { convert } from 'openapi-to-postmanv2'; -import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman/src/index'; -import { Folder, HttpRequest, Workspace, Environment } from '@yaakapp/api'; +import { convertPostman } from '@yaakapp/importer-postman/src'; type AtLeast = Partial & Pick; @@ -12,8 +11,17 @@ interface ExportResources { folders: AtLeast[]; } -export async function pluginHookImport( - ctx: Context, +export const plugin: PluginDefinition = { + importer: { + name: 'OpenAPI', + description: 'Import OpenAPI collections', + onImport(_ctx: Context, args: { text: string }) { + return convertOpenApi(args.text) as any; + }, + }, +}; + +export async function convertOpenApi( contents: string, ): Promise<{ resources: ExportResources } | undefined> { let postmanCollection; @@ -32,5 +40,5 @@ export async function pluginHookImport( return undefined; } - return pluginHookImportPostman(ctx, JSON.stringify(postmanCollection)); + return convertPostman(JSON.stringify(postmanCollection)); } diff --git a/plugins/importer-openapi/tests/index.test.ts b/plugins/importer-openapi/tests/index.test.ts index 29a2ce310..1e79c3557 100644 --- a/plugins/importer-openapi/tests/index.test.ts +++ b/plugins/importer-openapi/tests/index.test.ts @@ -1,24 +1,21 @@ -import { Context } from '@yaakapp/api'; import * as fs from 'node:fs'; import * as path from 'node:path'; import { describe, expect, test } from 'vitest'; -import { pluginHookImport } from '../src'; - -const ctx = {} as Context; +import { convertOpenApi } from '../src'; describe('importer-openapi', () => { const p = path.join(__dirname, 'fixtures'); const fixtures = fs.readdirSync(p); test('Skips invalid file', async () => { - const imported = await pluginHookImport(ctx, '{}'); + const imported = await convertOpenApi('{}'); expect(imported).toBeUndefined(); - }) + }); for (const fixture of fixtures) { test('Imports ' + fixture, async () => { const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); - const imported = await pluginHookImport(ctx, contents); + const imported = await convertOpenApi(contents); expect(imported?.resources.workspaces).toEqual([ expect.objectContaining({ name: 'Swagger Petstore - OpenAPI 3.0', diff --git a/plugins/importer-postman/src/index.ts b/plugins/importer-postman/src/index.ts index 93c25348b..b73aee150 100644 --- a/plugins/importer-postman/src/index.ts +++ b/plugins/importer-postman/src/index.ts @@ -5,6 +5,7 @@ import { HttpRequest, HttpRequestHeader, HttpUrlParameter, + PluginDefinition, Workspace, } from '@yaakapp/api'; @@ -21,8 +22,17 @@ interface ExportResources { folders: AtLeast[]; } -export function pluginHookImport( - _ctx: Context, +export const plugin: PluginDefinition = { + importer: { + name: 'Postman', + description: 'Import postman collections', + onImport(_ctx: Context, args: { text: string }) { + return convertPostman(args.text) as any; + }, + }, +}; + +export function convertPostman( contents: string, ): { resources: ExportResources } | undefined { const root = parseJSONToRecord(contents); diff --git a/plugins/importer-postman/tests/index.test.ts b/plugins/importer-postman/tests/index.test.ts index 350662696..3311605ae 100644 --- a/plugins/importer-postman/tests/index.test.ts +++ b/plugins/importer-postman/tests/index.test.ts @@ -1,10 +1,7 @@ -import { Context } from '@yaakapp/api'; import * as fs from 'node:fs'; import * as path from 'node:path'; import { describe, expect, test } from 'vitest'; -import { pluginHookImport } from '../src'; - -const ctx = {} as Context; +import { convertPostman } from '../src'; describe('importer-postman', () => { const p = path.join(__dirname, 'fixtures'); @@ -18,7 +15,7 @@ describe('importer-postman', () => { test('Imports ' + fixture, () => { const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); const expected = fs.readFileSync(path.join(p, fixture.replace('.input', '.output')), 'utf-8'); - const result = pluginHookImport(ctx, contents); + const result = convertPostman(contents); // console.log(JSON.stringify(result, null, 2)) expect(result).toEqual(JSON.parse(expected)); }); diff --git a/plugins/importer-yaak/src/index.ts b/plugins/importer-yaak/src/index.ts index 136bc745d..d42953588 100644 --- a/plugins/importer-yaak/src/index.ts +++ b/plugins/importer-yaak/src/index.ts @@ -1,6 +1,16 @@ -import { Context, Environment } from '@yaakapp/api'; +import { Environment, PluginDefinition } from '@yaakapp/api'; -export function pluginHookImport(_ctx: Context, contents: string) { +export const plugin: PluginDefinition = { + importer: { + name: 'Yaak', + description: 'Yaak official format', + onImport(_ctx, args) { + return migrateImport(args.text) as any; + }, + }, +}; + +export function migrateImport(contents: string) { let parsed; try { parsed = JSON.parse(contents); diff --git a/plugins/importer-yaak/tests/index.test.ts b/plugins/importer-yaak/tests/index.test.ts index 3c47c35a8..533acd6e7 100644 --- a/plugins/importer-yaak/tests/index.test.ts +++ b/plugins/importer-yaak/tests/index.test.ts @@ -1,19 +1,15 @@ -import { Context } from '@yaakapp/api'; import { describe, expect, test } from 'vitest'; -import { pluginHookImport } from '../src'; - -const ctx = {} as Context; +import { migrateImport } from '../src'; describe('importer-yaak', () => { test('Skips invalid imports', () => { - expect(pluginHookImport(ctx, 'not JSON')).toBeUndefined(); - expect(pluginHookImport(ctx, '[]')).toBeUndefined(); - expect(pluginHookImport(ctx, JSON.stringify({ resources: {} }))).toBeUndefined(); + expect(migrateImport('not JSON')).toBeUndefined(); + expect(migrateImport('[]')).toBeUndefined(); + expect(migrateImport(JSON.stringify({ resources: {} }))).toBeUndefined(); }); test('converts schema 1 to 2', () => { - const imported = pluginHookImport( - ctx, + const imported = migrateImport( JSON.stringify({ yaakSchema: 1, resources: { @@ -31,8 +27,7 @@ describe('importer-yaak', () => { ); }); test('converts schema 2 to 3', () => { - const imported = pluginHookImport( - ctx, + const imported = migrateImport( JSON.stringify({ yaakSchema: 2, resources: { From 252d23bb0e319c0c124c70ac7a7f0ba5ab2b46bb Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 26 Jan 2025 13:32:17 -0800 Subject: [PATCH 056/996] Support for OAuth 2.0 (#5) --- package-lock.json | 16 +- package.json | 2 +- plugins/auth-basic/src/index.ts | 6 +- plugins/auth-bearer/src/index.ts | 6 +- plugins/auth-jwt/src/index.ts | 13 +- plugins/auth-oauth2/package.json | 9 + plugins/auth-oauth2/src/getAccessToken.ts | 71 ++++ .../src/getOrRefreshAccessToken.ts | 99 ++++++ .../src/grants/authorizationCode.ts | 126 +++++++ .../src/grants/clientCredentials.ts | 40 +++ plugins/auth-oauth2/src/grants/implicit.ts | 70 ++++ plugins/auth-oauth2/src/grants/password.ts | 52 +++ plugins/auth-oauth2/src/index.ts | 311 ++++++++++++++++++ plugins/auth-oauth2/src/store.ts | 42 +++ plugins/exporter-curl/src/index.ts | 5 +- .../template-function-response/src/index.ts | 15 +- scripts/build-plugins.cjs | 24 -- 17 files changed, 855 insertions(+), 52 deletions(-) create mode 100644 plugins/auth-oauth2/package.json create mode 100644 plugins/auth-oauth2/src/getAccessToken.ts create mode 100644 plugins/auth-oauth2/src/getOrRefreshAccessToken.ts create mode 100644 plugins/auth-oauth2/src/grants/authorizationCode.ts create mode 100644 plugins/auth-oauth2/src/grants/clientCredentials.ts create mode 100644 plugins/auth-oauth2/src/grants/implicit.ts create mode 100644 plugins/auth-oauth2/src/grants/password.ts create mode 100644 plugins/auth-oauth2/src/index.ts create mode 100644 plugins/auth-oauth2/src/store.ts delete mode 100644 scripts/build-plugins.cjs diff --git a/package-lock.json b/package-lock.json index 84eb4190f..0c07682f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.3.4" + "@yaakapp/api": "^0.4.0" }, "devDependencies": { "@types/node": "^22.7.4", @@ -930,9 +930,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.3.4.tgz", - "integrity": "sha512-Yx0wigj+Re8cnYM1PJijTisRIL8jFeK50nJ66Hiv/OxPhX2QjqDWmOXGZ3TsRU9NB41JM74O1OfafRMhfeSUMw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.4.0.tgz", + "integrity": "sha512-F5yw9lxqomNtcYw0HtQvtWuKrOsXF7sD843zChaLMIY28gGkBpRJW9yO9D9h8AmG15oB87od3QHyW+fIFAsYxQ==", "dependencies": { "@types/node": "^22.5.4" } @@ -949,6 +949,10 @@ "resolved": "plugins/auth-jwt", "link": true }, + "node_modules/@yaakapp/auth-oauth2": { + "resolved": "plugins/auth-oauth2", + "link": true + }, "node_modules/@yaakapp/exporter-curl": { "resolved": "plugins/exporter-curl", "link": true @@ -7131,6 +7135,10 @@ "@types/jsonwebtoken": "^9.0.7" } }, + "plugins/auth-oauth2": { + "name": "@yaakapp/auth-oauth2", + "version": "0.0.1" + }, "plugins/exporter-curl": { "name": "@yaakapp/exporter-curl", "version": "0.0.1" diff --git a/package.json b/package.json index cf4190652..bf717486c 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.3.4" + "@yaakapp/api": "^0.4.0" } } diff --git a/plugins/auth-basic/src/index.ts b/plugins/auth-basic/src/index.ts index 342b3cf12..12f99a36f 100644 --- a/plugins/auth-basic/src/index.ts +++ b/plugins/auth-basic/src/index.ts @@ -5,7 +5,7 @@ export const plugin: PluginDefinition = { name: 'basic', label: 'Basic Auth', shortLabel: 'Basic', - config: [{ + args: [{ type: 'text', name: 'username', label: 'Username', @@ -17,8 +17,8 @@ export const plugin: PluginDefinition = { optional: true, password: true, }], - async onApply(_ctx, args) { - const { username, password } = args.config; + async onApply(_ctx, { values }) { + const { username, password } = values; const value = 'Basic ' + Buffer.from(`${username}:${password}`).toString('base64'); return { setHeaders: [{ name: 'Authorization', value }] }; }, diff --git a/plugins/auth-bearer/src/index.ts b/plugins/auth-bearer/src/index.ts index a08a5dd36..6c6ec6b40 100644 --- a/plugins/auth-bearer/src/index.ts +++ b/plugins/auth-bearer/src/index.ts @@ -5,15 +5,15 @@ export const plugin: PluginDefinition = { name: 'bearer', label: 'Bearer Token', shortLabel: 'Bearer', - config: [{ + args: [{ type: 'text', name: 'token', label: 'Token', optional: true, password: true, }], - async onApply(_ctx, args) { - const { token } = args.config; + async onApply(_ctx, { values }) { + const { token } = values; const value = `Bearer ${token}`.trim(); return { setHeaders: [{ name: 'Authorization', value }] }; }, diff --git a/plugins/auth-jwt/src/index.ts b/plugins/auth-jwt/src/index.ts index 9edc25215..45b20a53b 100644 --- a/plugins/auth-jwt/src/index.ts +++ b/plugins/auth-jwt/src/index.ts @@ -24,21 +24,22 @@ export const plugin: PluginDefinition = { name: 'jwt', label: 'JWT Bearer', shortLabel: 'JWT', - config: [ + args: [ { type: 'select', name: 'algorithm', label: 'Algorithm', hideLabel: true, defaultValue: defaultAlgorithm, - options: algorithms.map(value => ({ name: value === 'none' ? 'None' : value, value })), + options: algorithms.map(value => ({ label: value === 'none' ? 'None' : value, value })), }, { - type: 'editor', + type: 'text', name: 'secret', label: 'Secret or Private Key', + password: true, optional: true, - hideGutter: true, + multiLine: true, }, { type: 'checkbox', @@ -54,8 +55,8 @@ export const plugin: PluginDefinition = { placeholder: '{ }', }, ], - async onApply(_ctx, args) { - const { algorithm, secret: _secret, secretBase64, payload } = args.config; + async onApply(_ctx, { values }) { + const { algorithm, secret: _secret, secretBase64, payload } = values; const secret = secretBase64 ? Buffer.from(`${_secret}`, 'base64') : `${_secret}`; const token = jwt.sign(`${payload}`, secret, { algorithm: algorithm as any }); const value = `Bearer ${token}`; diff --git a/plugins/auth-oauth2/package.json b/plugins/auth-oauth2/package.json new file mode 100644 index 000000000..696aa318d --- /dev/null +++ b/plugins/auth-oauth2/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/auth-oauth2", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/plugins/auth-oauth2/src/getAccessToken.ts b/plugins/auth-oauth2/src/getAccessToken.ts new file mode 100644 index 000000000..6d04a379d --- /dev/null +++ b/plugins/auth-oauth2/src/getAccessToken.ts @@ -0,0 +1,71 @@ +import { Context, HttpRequest, HttpUrlParameter } from '@yaakapp/api'; +import { readFileSync } from 'node:fs'; +import { AccessTokenRawResponse } from './store'; + +export async function getAccessToken( + ctx: Context, { + accessTokenUrl, + scope, + params, + grantType, + credentialsInBody, + clientId, + clientSecret, + }: { + clientId: string; + clientSecret: string; + grantType: string; + accessTokenUrl: string; + scope: string | null; + credentialsInBody: boolean; + params: HttpUrlParameter[]; + }): Promise { + console.log('Getting access token', accessTokenUrl); + const httpRequest: Partial = { + method: 'POST', + url: accessTokenUrl, + bodyType: 'application/x-www-form-urlencoded', + body: { + form: [ + { name: 'grant_type', value: grantType }, + ...params, + ], + }, + headers: [ + { name: 'User-Agent', value: 'yaak' }, + { name: 'Accept', value: 'application/x-www-form-urlencoded, application/json' }, + { name: 'Content-Type', value: 'application/x-www-form-urlencoded' }, + ], + }; + + if (scope) httpRequest.body!.form.push({ name: 'scope', value: scope }); + + if (credentialsInBody) { + httpRequest.body!.form.push({ name: 'client_id', value: clientId }); + httpRequest.body!.form.push({ name: 'client_secret', value: clientSecret }); + } else { + const value = 'Basic ' + Buffer.from(`${clientId}:${clientSecret}`).toString('base64'); + httpRequest.headers!.push({ name: 'Authorization', value }); + } + + const resp = await ctx.httpRequest.send({ httpRequest }); + + if (resp.status < 200 || resp.status >= 300) { + throw new Error('Failed to fetch access token with status=' + resp.status); + } + + const body = readFileSync(resp.bodyPath ?? '', 'utf8'); + + let response; + try { + response = JSON.parse(body); + } catch { + response = Object.fromEntries(new URLSearchParams(body)); + } + + if (response.error) { + throw new Error('Failed to fetch access token with ' + response.error); + } + + return response; +} diff --git a/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts b/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts new file mode 100644 index 000000000..02b202032 --- /dev/null +++ b/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts @@ -0,0 +1,99 @@ +import { Context, HttpRequest } from '@yaakapp/api'; +import { readFileSync } from 'node:fs'; +import { AccessToken, AccessTokenRawResponse, deleteToken, getToken, storeToken } from './store'; + +export async function getOrRefreshAccessToken(ctx: Context, contextId: string, { + scope, + accessTokenUrl, + credentialsInBody, + clientId, + clientSecret, + forceRefresh, +}: { + scope: string | null; + accessTokenUrl: string; + credentialsInBody: boolean; + clientId: string; + clientSecret: string; + forceRefresh?: boolean; +}): Promise { + const token = await getToken(ctx, contextId); + if (token == null) { + return null; + } + + const now = (Date.now() / 1000); + const isExpired = token.expiresAt && now > token.expiresAt; + + // Return the current access token if it's still valid + if (!isExpired && !forceRefresh) { + return token; + } + + // Token is expired, but there's no refresh token :( + if (!token.response.refresh_token) { + return null; + } + + // Access token is expired, so get a new one + const httpRequest: Partial = { + method: 'POST', + url: accessTokenUrl, + bodyType: 'application/x-www-form-urlencoded', + body: { + form: [ + { name: 'grant_type', value: 'refresh_token' }, + { name: 'refresh_token', value: token.response.refresh_token }, + ], + }, + headers: [ + { name: 'User-Agent', value: 'yaak' }, + { name: 'Accept', value: 'application/x-www-form-urlencoded, application/json' }, + { name: 'Content-Type', value: 'application/x-www-form-urlencoded' }, + ], + }; + + if (scope) httpRequest.body!.form.push({ name: 'scope', value: scope }); + + if (credentialsInBody) { + httpRequest.body!.form.push({ name: 'client_id', value: clientId }); + httpRequest.body!.form.push({ name: 'client_secret', value: clientSecret }); + } else { + const value = 'Basic ' + Buffer.from(`${clientId}:${clientSecret}`).toString('base64'); + httpRequest.headers!.push({ name: 'Authorization', value }); + } + + const resp = await ctx.httpRequest.send({ httpRequest }); + + if (resp.status === 401) { + // Bad refresh token, so we'll force it to fetch a fresh access token by deleting + // and returning null; + console.log('Unauthorized refresh_token request'); + await deleteToken(ctx, contextId); + return null; + } + + if (resp.status < 200 || resp.status >= 300) { + throw new Error('Failed to fetch access token with status=' + resp.status); + } + + const body = readFileSync(resp.bodyPath ?? '', 'utf8'); + + let response; + try { + response = JSON.parse(body); + } catch { + response = Object.fromEntries(new URLSearchParams(body)); + } + + if (response.error) { + throw new Error(`Failed to fetch access token with ${response.error} -> ${response.error_description}`); + } + + const newResponse: AccessTokenRawResponse = { + ...response, + // Assign a new one or keep the old one, + refresh_token: response.refresh_token ?? token.response.refresh_token, + }; + return storeToken(ctx, contextId, newResponse); +} diff --git a/plugins/auth-oauth2/src/grants/authorizationCode.ts b/plugins/auth-oauth2/src/grants/authorizationCode.ts new file mode 100644 index 000000000..8d06dd7a7 --- /dev/null +++ b/plugins/auth-oauth2/src/grants/authorizationCode.ts @@ -0,0 +1,126 @@ +import { Context } from '@yaakapp/api'; +import { createHash, randomBytes } from 'node:crypto'; +import { getAccessToken } from '../getAccessToken'; +import { getOrRefreshAccessToken } from '../getOrRefreshAccessToken'; +import { AccessToken, storeToken } from '../store'; + +export const PKCE_SHA256 = 'S256'; +export const PKCE_PLAIN = 'plain'; +export const DEFAULT_PKCE_METHOD = PKCE_SHA256; + +export async function getAuthorizationCode( + ctx: Context, + contextId: string, + { + authorizationUrl: authorizationUrlRaw, + accessTokenUrl, + clientId, + clientSecret, + redirectUri, + scope, + state, + credentialsInBody, + pkce, + }: { + authorizationUrl: string; + accessTokenUrl: string; + clientId: string; + clientSecret: string; + redirectUri: string | null; + scope: string | null; + state: string | null; + credentialsInBody: boolean; + pkce: { + challengeMethod: string | null; + codeVerifier: string | null; + } | null; + }, +): Promise { + const token = await getOrRefreshAccessToken(ctx, contextId, { + accessTokenUrl, + scope, + clientId, + clientSecret, + credentialsInBody, + }); + if (token != null) { + return token; + } + + const authorizationUrl = new URL(`${authorizationUrlRaw ?? ''}`); + authorizationUrl.searchParams.set('response_type', 'code'); + authorizationUrl.searchParams.set('client_id', clientId); + if (redirectUri) authorizationUrl.searchParams.set('redirect_uri', redirectUri); + if (scope) authorizationUrl.searchParams.set('scope', scope); + if (state) authorizationUrl.searchParams.set('state', state); + if (pkce) { + const verifier = pkce.codeVerifier || createPkceCodeVerifier(); + const challengeMethod = pkce.challengeMethod || DEFAULT_PKCE_METHOD; + authorizationUrl.searchParams.set('code_challenge', createPkceCodeChallenge(verifier, challengeMethod)); + authorizationUrl.searchParams.set('code_challenge_method', challengeMethod); + } + + return new Promise(async (resolve, reject) => { + const authorizationUrlStr = authorizationUrl.toString(); + console.log('Authorizing', authorizationUrlStr); + let { close } = await ctx.window.openUrl({ + url: authorizationUrlStr, + label: 'oauth-authorization-url', + async onNavigate({ url: urlStr }) { + const url = new URL(urlStr); + if (url.searchParams.has('error')) { + return reject(new Error(`Failed to authorize: ${url.searchParams.get('error')}`)); + } + const code = url.searchParams.get('code'); + if (!code) { + return; // Could be one of many redirects in a chain, so skip it + } + + // Close the window here, because we don't need it anymore! + close(); + + const response = await getAccessToken(ctx, { + grantType: 'authorization_code', + accessTokenUrl, + clientId, + clientSecret, + scope, + credentialsInBody, + params: [ + { name: 'code', value: code }, + ...(redirectUri ? [{ name: 'redirect_uri', value: redirectUri }] : []), + ], + }); + + try { + resolve(await storeToken(ctx, contextId, response)); + } catch (err) { + reject(err); + } + }, + }); + }); +} + +function createPkceCodeVerifier() { + return encodeForPkce(randomBytes(32)); +} + +function createPkceCodeChallenge(verifier: string, method: string) { + if (method === 'plain') { + return verifier; + } + + const hash = encodeForPkce(createHash('sha256').update(verifier).digest()); + return hash + .replace(/=/g, '') // Remove padding '=' + .replace(/\+/g, '-') // Replace '+' with '-' + .replace(/\//g, '_'); // Replace '/' with '_' +} + +function encodeForPkce(bytes: Buffer) { + return bytes.toString('base64') + .replace(/=/g, '') // Remove padding '=' + .replace(/\+/g, '-') // Replace '+' with '-' + .replace(/\//g, '_'); // Replace '/' with '_' +} diff --git a/plugins/auth-oauth2/src/grants/clientCredentials.ts b/plugins/auth-oauth2/src/grants/clientCredentials.ts new file mode 100644 index 000000000..6fb8e6e4c --- /dev/null +++ b/plugins/auth-oauth2/src/grants/clientCredentials.ts @@ -0,0 +1,40 @@ +import { Context } from '@yaakapp/api'; +import { getAccessToken } from '../getAccessToken'; +import { getToken, storeToken } from '../store'; + +export async function getClientCredentials( + ctx: Context, + contextId: string, + { + accessTokenUrl, + clientId, + clientSecret, + scope, + credentialsInBody, + }: { + accessTokenUrl: string; + clientId: string; + clientSecret: string; + scope: string | null; + credentialsInBody: boolean; + }, +) { + const token = await getToken(ctx, contextId); + if (token) { + // resolve(token.response.access_token); + // TODO: Refresh token if expired + // return; + } + + const response = await getAccessToken(ctx, { + grantType: 'client_credentials', + accessTokenUrl, + clientId, + clientSecret, + scope, + credentialsInBody, + params: [], + }); + + return storeToken(ctx, contextId, response); +} diff --git a/plugins/auth-oauth2/src/grants/implicit.ts b/plugins/auth-oauth2/src/grants/implicit.ts new file mode 100644 index 000000000..15105b0f6 --- /dev/null +++ b/plugins/auth-oauth2/src/grants/implicit.ts @@ -0,0 +1,70 @@ +import { Context } from '@yaakapp/api'; +import { AccessToken, AccessTokenRawResponse, getToken, storeToken } from '../store'; + +export function getImplicit( + ctx: Context, + contextId: string, + { + authorizationUrl: authorizationUrlRaw, + responseType, + clientId, + redirectUri, + scope, + state, + }: { + authorizationUrl: string; + responseType: string; + clientId: string; + redirectUri: string | null; + scope: string | null; + state: string | null; + }, +) :Promise { + return new Promise(async (resolve, reject) => { + const token = await getToken(ctx, contextId); + if (token) { + // resolve(token.response.access_token); + // TODO: Refresh token if expired + // return; + } + + const authorizationUrl = new URL(`${authorizationUrlRaw ?? ''}`); + authorizationUrl.searchParams.set('response_type', 'code'); + authorizationUrl.searchParams.set('client_id', clientId); + if (redirectUri) authorizationUrl.searchParams.set('redirect_uri', redirectUri); + if (scope) authorizationUrl.searchParams.set('scope', scope); + if (state) authorizationUrl.searchParams.set('state', state); + if (responseType.includes('id_token')) { + authorizationUrl.searchParams.set('nonce', String(Math.floor(Math.random() * 9999999999999) + 1)); + } + + const authorizationUrlStr = authorizationUrl.toString(); + let { close } = await ctx.window.openUrl({ + url: authorizationUrlStr, + label: 'oauth-authorization-url', + async onNavigate({ url: urlStr }) { + const url = new URL(urlStr); + if (url.searchParams.has('error')) { + return reject(Error(`Failed to authorize: ${url.searchParams.get('error')}`)); + } + + // Close the window here, because we don't need it anymore + close(); + + const hash = url.hash.slice(1); + const params = new URLSearchParams(hash); + const idToken = params.get('id_token'); + if (idToken) { + params.set('access_token', idToken); + params.delete('id_token'); + } + const response = Object.fromEntries(params) as unknown as AccessTokenRawResponse; + try { + resolve(await storeToken(ctx, contextId, response)); + } catch (err) { + reject(err); + } + }, + }); + }); +} diff --git a/plugins/auth-oauth2/src/grants/password.ts b/plugins/auth-oauth2/src/grants/password.ts new file mode 100644 index 000000000..f1a685da7 --- /dev/null +++ b/plugins/auth-oauth2/src/grants/password.ts @@ -0,0 +1,52 @@ +import { Context } from '@yaakapp/api'; +import { getAccessToken } from '../getAccessToken'; +import { getOrRefreshAccessToken } from '../getOrRefreshAccessToken'; +import { AccessToken, storeToken } from '../store'; + +export async function getPassword( + ctx: Context, + contextId: string, + { + accessTokenUrl, + clientId, + clientSecret, + username, + password, + credentialsInBody, + scope, + }: { + accessTokenUrl: string; + clientId: string; + clientSecret: string; + username: string; + password: string; + scope: string | null; + credentialsInBody: boolean; + }, +): Promise { + const token = await getOrRefreshAccessToken(ctx, contextId, { + accessTokenUrl, + scope, + clientId, + clientSecret, + credentialsInBody, + }); + if (token != null) { + return token; + } + + const response = await getAccessToken(ctx, { + accessTokenUrl, + clientId, + clientSecret, + scope, + grantType: 'password', + credentialsInBody, + params: [ + { name: 'username', value: username }, + { name: 'password', value: password }, + ], + }); + + return storeToken(ctx, contextId, response); +} diff --git a/plugins/auth-oauth2/src/index.ts b/plugins/auth-oauth2/src/index.ts new file mode 100644 index 000000000..27779a696 --- /dev/null +++ b/plugins/auth-oauth2/src/index.ts @@ -0,0 +1,311 @@ +import { + Context, + FormInputSelectOption, + GetHttpAuthenticationConfigRequest, + JsonPrimitive, + PluginDefinition, +} from '@yaakapp/api'; +import { DEFAULT_PKCE_METHOD, getAuthorizationCode, PKCE_PLAIN, PKCE_SHA256 } from './grants/authorizationCode'; +import { getClientCredentials } from './grants/clientCredentials'; +import { getImplicit } from './grants/implicit'; +import { getPassword } from './grants/password'; +import { AccessToken, deleteToken, getToken } from './store'; + +type GrantType = 'authorization_code' | 'implicit' | 'password' | 'client_credentials'; + +const grantTypes: FormInputSelectOption[] = [ + { label: 'Authorization Code', value: 'authorization_code' }, + { label: 'Implicit', value: 'implicit' }, + { label: 'Resource Owner Password Credential', value: 'password' }, + { label: 'Client Credentials', value: 'client_credentials' }, +]; + +const defaultGrantType = grantTypes[0]!.value; + +function hiddenIfNot(grantTypes: GrantType[], ...other: ((values: GetHttpAuthenticationConfigRequest['values']) => boolean)[]) { + return (_ctx: Context, { values }: GetHttpAuthenticationConfigRequest) => { + const hasGrantType = grantTypes.find(t => t === String(values.grantType ?? defaultGrantType)); + const hasOtherBools = other.every(t => t(values)); + const show = hasGrantType && hasOtherBools; + return { hidden: !show }; + }; +} + +const authorizationUrls = [ + 'https://github.com/login/oauth/authorize', + 'https://account.box.com/api/oauth2/authorize', + 'https://accounts.google.com/o/oauth2/v2/auth', + 'https://api.imgur.com/oauth2/authorize', + 'https://bitly.com/oauth/authorize', + 'https://gitlab.example.com/oauth/authorize', + 'https://medium.com/m/oauth/authorize', + 'https://public-api.wordpress.com/oauth2/authorize', + 'https://slack.com/oauth/authorize', + 'https://todoist.com/oauth/authorize', + 'https://www.dropbox.com/oauth2/authorize', + 'https://www.linkedin.com/oauth/v2/authorization', + 'https://MY_SHOP.myshopify.com/admin/oauth/access_token', +]; + +const accessTokenUrls = [ + 'https://github.com/login/oauth/access_token', + 'https://api-ssl.bitly.com/oauth/access_token', + 'https://api.box.com/oauth2/token', + 'https://api.dropboxapi.com/oauth2/token', + 'https://api.imgur.com/oauth2/token', + 'https://api.medium.com/v1/tokens', + 'https://gitlab.example.com/oauth/token', + 'https://public-api.wordpress.com/oauth2/token', + 'https://slack.com/api/oauth.access', + 'https://todoist.com/oauth/access_token', + 'https://www.googleapis.com/oauth2/v4/token', + 'https://www.linkedin.com/oauth/v2/accessToken', + 'https://MY_SHOP.myshopify.com/admin/oauth/authorize', +]; + +export const plugin: PluginDefinition = { + authentication: { + name: 'oauth2', + label: 'OAuth 2.0', + shortLabel: 'OAuth 2', + actions: [ + { + label: 'Copy Current Token', + icon: 'copy', + async onSelect(ctx, { contextId }) { + const token = await getToken(ctx, contextId); + if (token == null) { + await ctx.toast.show({ message: 'No token to copy', color: 'warning' }); + } else { + await ctx.clipboard.copyText(token.response.access_token); + await ctx.toast.show({ message: 'Token copied to clipboard', icon: 'copy', color: 'success' }); + } + }, + }, + { + label: 'Delete Token', + icon: 'trash', + async onSelect(ctx, { contextId }) { + if (await deleteToken(ctx, contextId)) { + await ctx.toast.show({ message: 'Token deleted', color: 'success' }); + } else { + await ctx.toast.show({ message: 'No token to delete', color: 'warning' }); + } + }, + }, + ], + args: [ + { + type: 'select', + name: 'grantType', + label: 'Grant Type', + hideLabel: true, + defaultValue: defaultGrantType, + options: grantTypes, + }, + // Always-present fields + { type: 'text', name: 'clientId', label: 'Client ID' }, + + { + type: 'text', + name: 'clientSecret', + label: 'Client Secret', + password: true, + dynamic: hiddenIfNot(['authorization_code', 'password', 'client_credentials']), + }, + { + type: 'text', + name: 'authorizationUrl', + label: 'Authorization URL', + dynamic: hiddenIfNot(['authorization_code', 'implicit']), + placeholder: authorizationUrls[0], + completionOptions: authorizationUrls.map(url => ({ label: url, value: url })), + }, + { + type: 'text', + name: 'accessTokenUrl', + label: 'Access Token URL', + placeholder: accessTokenUrls[0], + dynamic: hiddenIfNot(['authorization_code', 'password', 'client_credentials']), + completionOptions: accessTokenUrls.map(url => ({ label: url, value: url })), + }, + { + type: 'text', + name: 'redirectUri', + label: 'Redirect URI', + optional: true, + dynamic: hiddenIfNot(['authorization_code', 'implicit']), + }, + { + type: 'text', + name: 'state', + label: 'State', + optional: true, + dynamic: hiddenIfNot(['authorization_code', 'implicit']), + }, + { + type: 'checkbox', + name: 'usePkce', + label: 'Use PKCE', + dynamic: hiddenIfNot(['authorization_code']), + }, + { + type: 'select', + name: 'pkceChallengeMethod', + label: 'Code Challenge Method', + options: [{ label: 'SHA-256', value: PKCE_SHA256 }, { label: 'Plain', value: PKCE_PLAIN }], + defaultValue: DEFAULT_PKCE_METHOD, + dynamic: hiddenIfNot(['authorization_code'], ({ usePkce }) => !!usePkce), + }, + { + type: 'text', + name: 'pkceCodeVerifier', + label: 'Code Verifier', + placeholder: 'Automatically generated if not provided', + optional: true, + dynamic: hiddenIfNot(['authorization_code'], ({ usePkce }) => !!usePkce), + }, + { + type: 'text', + name: 'username', + label: 'Username', + optional: true, + dynamic: hiddenIfNot(['password']), + }, + { + type: 'text', + name: 'password', + label: 'Password', + password: true, + optional: true, + dynamic: hiddenIfNot(['password']), + }, + { + type: 'select', + name: 'responseType', + label: 'Response Type', + defaultValue: 'token', + options: [ + { label: 'Access Token', value: 'token' }, + { label: 'ID Token', value: 'id_token' }, + { label: 'ID and Access Token', value: 'id_token token' }, + ], + dynamic: hiddenIfNot(['implicit']), + }, + { + type: 'accordion', + label: 'Advanced', + inputs: [ + { type: 'text', name: 'scope', label: 'Scope', optional: true }, + { type: 'text', name: 'headerPrefix', label: 'Header Prefix', optional: true, defaultValue: 'Bearer' }, + { + type: 'select', name: 'credentials', label: 'Send Credentials', defaultValue: 'body', options: [ + { label: 'In Request Body', value: 'body' }, + { label: 'As Basic Authentication', value: 'basic' }, + ], + }, + ], + }, + { + type: 'accordion', + label: 'Access Token Response', + async dynamic(ctx, { contextId }) { + const token = await getToken(ctx, contextId); + if (token == null) { + return { hidden: true }; + } + return { + label: 'Access Token Response', + inputs: [ + { + type: 'editor', + defaultValue: JSON.stringify(token.response, null, 2), + hideLabel: true, + readOnly: true, + language: 'json', + }, + ], + }; + }, + }, + ], + async onApply(ctx, { values, contextId }) { + const headerPrefix = optionalString(values, 'headerPrefix') ?? ''; + const grantType = requiredString(values, 'grantType') as GrantType; + const credentialsInBody = values.credentials === 'body'; + + console.log('Performing OAuth', values); + let token: AccessToken; + if (grantType === 'authorization_code') { + const authorizationUrl = requiredString(values, 'authorizationUrl'); + const accessTokenUrl = requiredString(values, 'accessTokenUrl'); + token = await getAuthorizationCode(ctx, contextId, { + accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`, + authorizationUrl: authorizationUrl.match(/^https?:\/\//) ? authorizationUrl : `https://${authorizationUrl}`, + clientId: requiredString(values, 'clientId'), + clientSecret: requiredString(values, 'clientSecret'), + redirectUri: optionalString(values, 'redirectUri'), + scope: optionalString(values, 'scope'), + state: optionalString(values, 'state'), + credentialsInBody, + pkce: values.usePkce ? { + challengeMethod: requiredString(values, 'pkceChallengeMethod'), + codeVerifier: optionalString(values, 'pkceCodeVerifier'), + } : null, + }); + } else if (grantType === 'implicit') { + const authorizationUrl = requiredString(values, 'authorizationUrl'); + token = await getImplicit(ctx, contextId, { + authorizationUrl: authorizationUrl.match(/^https?:\/\//) ? authorizationUrl : `https://${authorizationUrl}`, + clientId: requiredString(values, 'clientId'), + redirectUri: optionalString(values, 'redirectUri'), + responseType: requiredString(values, 'responseType'), + scope: optionalString(values, 'scope'), + state: optionalString(values, 'state'), + }); + } else if (grantType === 'client_credentials') { + const accessTokenUrl = requiredString(values, 'accessTokenUrl'); + token = await getClientCredentials(ctx, contextId, { + accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`, + clientId: requiredString(values, 'clientId'), + clientSecret: requiredString(values, 'clientSecret'), + scope: optionalString(values, 'scope'), + credentialsInBody, + }); + } else if (grantType === 'password') { + const accessTokenUrl = requiredString(values, 'accessTokenUrl'); + token = await getPassword(ctx, contextId, { + accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`, + clientId: requiredString(values, 'clientId'), + clientSecret: requiredString(values, 'clientSecret'), + username: requiredString(values, 'username'), + password: requiredString(values, 'password'), + scope: optionalString(values, 'scope'), + credentialsInBody, + }); + } else { + throw new Error('Invalid grant type ' + grantType); + } + + const headerValue = `${headerPrefix} ${token.response.access_token}`.trim(); + return { + setHeaders: [{ + name: 'Authorization', + value: headerValue, + }], + }; + }, + }, +}; + +function optionalString(values: Record, name: string): string | null { + const arg = values[name]; + if (arg == null || arg == '') return null; + return `${arg}`; +} + +function requiredString(values: Record, name: string): string { + const arg = optionalString(values, name); + if (!arg) throw new Error(`Missing required argument ${name}`); + return arg; +} diff --git a/plugins/auth-oauth2/src/store.ts b/plugins/auth-oauth2/src/store.ts new file mode 100644 index 000000000..bc1675ed9 --- /dev/null +++ b/plugins/auth-oauth2/src/store.ts @@ -0,0 +1,42 @@ +import { Context } from '@yaakapp/api'; + +export async function storeToken(ctx: Context, contextId: string, response: AccessTokenRawResponse) { + if (!response.access_token) { + throw new Error(`Token not found in response`); + } + + const expiresAt = response.expires_in ? Date.now() + response.expires_in * 1000 : null; + const token: AccessToken = { + response, + expiresAt, + }; + await ctx.store.set(tokenStoreKey(contextId), token); + return token; +} + +export async function getToken(ctx: Context, contextId: string) { + return ctx.store.get(tokenStoreKey(contextId)); +} + +export async function deleteToken(ctx: Context, contextId: string) { + return ctx.store.delete(tokenStoreKey(contextId)); +} + +function tokenStoreKey(context_id: string) { + return ['token', context_id].join('::'); +} + +export interface AccessToken { + response: AccessTokenRawResponse, + expiresAt: number | null; +} + +export interface AccessTokenRawResponse { + access_token: string; + token_type?: string; + expires_in?: number; + refresh_token?: string; + error?: string; + error_description?: string; + scope?: string; +} diff --git a/plugins/exporter-curl/src/index.ts b/plugins/exporter-curl/src/index.ts index fd90e7573..e8fa34154 100644 --- a/plugins/exporter-curl/src/index.ts +++ b/plugins/exporter-curl/src/index.ts @@ -4,14 +4,13 @@ const NEWLINE = '\\\n '; export const plugin: PluginDefinition = { httpRequestActions: [{ - key: 'export-curl', label: 'Copy as Curl', icon: 'copy', async onSelect(ctx, args) { const rendered_request = await ctx.httpRequest.render({ httpRequest: args.httpRequest, purpose: 'preview' }); const data = await convertToCurl(rendered_request); - ctx.clipboard.copyText(data); - ctx.toast.show({ message: 'Curl copied to clipboard', icon: 'copy' }); + await ctx.clipboard.copyText(data); + await ctx.toast.show({ message: 'Curl copied to clipboard', icon: 'copy', color: 'success' }); }, }], }; diff --git a/plugins/template-function-response/src/index.ts b/plugins/template-function-response/src/index.ts index 15a67a003..0e8c8909b 100644 --- a/plugins/template-function-response/src/index.ts +++ b/plugins/template-function-response/src/index.ts @@ -17,17 +17,16 @@ const behaviorArg: FormInput = { label: 'Sending Behavior', defaultValue: 'smart', options: [ - { name: 'When no responses', value: 'smart' }, - { name: 'Always', value: 'always' }, + { label: 'When no responses', value: 'smart' }, + { label: 'Always', value: 'always' }, ], }; -const requestArg: FormInput = - { - type: 'http_request', - name: 'request', - label: 'Request', - }; +const requestArg: FormInput = { + type: 'http_request', + name: 'request', + label: 'Request', +}; export const plugin: PluginDefinition = { templateFunctions: [ diff --git a/scripts/build-plugins.cjs b/scripts/build-plugins.cjs deleted file mode 100644 index 687fc73cd..000000000 --- a/scripts/build-plugins.cjs +++ /dev/null @@ -1,24 +0,0 @@ -const { readdirSync, readFileSync } = require('node:fs'); -const { execSync } = require('node:child_process'); -const path = require('node:path'); - -async function main() { - console.log('Building plugins'); - - const pluginsDir = path.join(__dirname, '../plugins'); - const pluginNames = readdirSync(pluginsDir); - - for (const dir of pluginNames) { - const pluginDir = path.join(pluginsDir, dir); - const pkg = JSON.parse(readFileSync(path.join(pluginDir, 'package.json'), 'utf8')); - - console.log('Building plugin', pkg.name, pluginDir); - execSync(`npm install`, { cwd: pluginDir }); - execSync(`npm run build`, { cwd: pluginDir }); - } -} - -main().catch(err => { - console.log('Failed', err); - process.exit(1); -}); From 1ae68378422bef92e2ac1b1a69dc5fb6e4e8e526 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 27 Jan 2025 08:37:54 -0800 Subject: [PATCH 057/996] Remove log --- plugins/auth-oauth2/src/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/auth-oauth2/src/index.ts b/plugins/auth-oauth2/src/index.ts index 27779a696..31e2b6ce0 100644 --- a/plugins/auth-oauth2/src/index.ts +++ b/plugins/auth-oauth2/src/index.ts @@ -234,7 +234,6 @@ export const plugin: PluginDefinition = { const grantType = requiredString(values, 'grantType') as GrantType; const credentialsInBody = values.credentials === 'body'; - console.log('Performing OAuth', values); let token: AccessToken; if (grantType === 'authorization_code') { const authorizationUrl = requiredString(values, 'authorizationUrl'); From 5f0b7055bf6f2e8fb9d76678cba65b77af5132f7 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 31 Jan 2025 09:05:09 -0800 Subject: [PATCH 058/996] Bump plugin types --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf717486c..29d6f4665 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.4.0" + "@yaakapp/api": "^0.4.1" } } From d9a1e124f549b8601ca76245112fcdb75286991d Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 31 Jan 2025 09:05:19 -0800 Subject: [PATCH 059/996] package-lock.json --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0c07682f4..9bf7fb642 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.4.0" + "@yaakapp/api": "^0.4.1" }, "devDependencies": { "@types/node": "^22.7.4", @@ -930,9 +930,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.4.0.tgz", - "integrity": "sha512-F5yw9lxqomNtcYw0HtQvtWuKrOsXF7sD843zChaLMIY28gGkBpRJW9yO9D9h8AmG15oB87od3QHyW+fIFAsYxQ==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.4.1.tgz", + "integrity": "sha512-qRpCuL2Wq9BJXbB6tHSQjaXGq0ZBQwnd87nWdeOPWMvmKCfFTPhxQh4x9/aFN1bTncNHcV3OdeXFTKMl0tB0Ng==", "dependencies": { "@types/node": "^22.5.4" } From 597b5bb783c6c72703ff1218f31610b3068f51b1 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 21 Feb 2025 13:40:05 -0800 Subject: [PATCH 060/996] Make all OAuth 2.0 fields optional Closes mountain-loop/yaak#165 --- plugins/auth-oauth2/src/index.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/plugins/auth-oauth2/src/index.ts b/plugins/auth-oauth2/src/index.ts index 31e2b6ce0..cb03dfae6 100644 --- a/plugins/auth-oauth2/src/index.ts +++ b/plugins/auth-oauth2/src/index.ts @@ -103,19 +103,27 @@ export const plugin: PluginDefinition = { defaultValue: defaultGrantType, options: grantTypes, }, + // Always-present fields - { type: 'text', name: 'clientId', label: 'Client ID' }, + { + type: 'text', + name: 'clientId', + label: 'Client ID', + optional: true, + }, { type: 'text', name: 'clientSecret', label: 'Client Secret', + optional: true, password: true, dynamic: hiddenIfNot(['authorization_code', 'password', 'client_credentials']), }, { type: 'text', name: 'authorizationUrl', + optional: true, label: 'Authorization URL', dynamic: hiddenIfNot(['authorization_code', 'implicit']), placeholder: authorizationUrls[0], @@ -124,6 +132,7 @@ export const plugin: PluginDefinition = { { type: 'text', name: 'accessTokenUrl', + optional: true, label: 'Access Token URL', placeholder: accessTokenUrls[0], dynamic: hiddenIfNot(['authorization_code', 'password', 'client_credentials']), From 52937c3097e8be5eb6f73ca306902f8dbd1aa6a2 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 21 Feb 2025 13:43:19 -0800 Subject: [PATCH 061/996] Soft required field --- plugins/auth-oauth2/src/index.ts | 62 ++++++++++++++++---------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/plugins/auth-oauth2/src/index.ts b/plugins/auth-oauth2/src/index.ts index cb03dfae6..43ade852b 100644 --- a/plugins/auth-oauth2/src/index.ts +++ b/plugins/auth-oauth2/src/index.ts @@ -239,56 +239,56 @@ export const plugin: PluginDefinition = { }, ], async onApply(ctx, { values, contextId }) { - const headerPrefix = optionalString(values, 'headerPrefix') ?? ''; - const grantType = requiredString(values, 'grantType') as GrantType; + const headerPrefix = stringArg(values, 'headerPrefix'); + const grantType = stringArg(values, 'grantType') as GrantType; const credentialsInBody = values.credentials === 'body'; let token: AccessToken; if (grantType === 'authorization_code') { - const authorizationUrl = requiredString(values, 'authorizationUrl'); - const accessTokenUrl = requiredString(values, 'accessTokenUrl'); + const authorizationUrl = stringArg(values, 'authorizationUrl'); + const accessTokenUrl = stringArg(values, 'accessTokenUrl'); token = await getAuthorizationCode(ctx, contextId, { accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`, authorizationUrl: authorizationUrl.match(/^https?:\/\//) ? authorizationUrl : `https://${authorizationUrl}`, - clientId: requiredString(values, 'clientId'), - clientSecret: requiredString(values, 'clientSecret'), - redirectUri: optionalString(values, 'redirectUri'), - scope: optionalString(values, 'scope'), - state: optionalString(values, 'state'), + clientId: stringArg(values, 'clientId'), + clientSecret: stringArg(values, 'clientSecret'), + redirectUri: stringArgOrNull(values, 'redirectUri'), + scope: stringArgOrNull(values, 'scope'), + state: stringArgOrNull(values, 'state'), credentialsInBody, pkce: values.usePkce ? { - challengeMethod: requiredString(values, 'pkceChallengeMethod'), - codeVerifier: optionalString(values, 'pkceCodeVerifier'), + challengeMethod: stringArg(values, 'pkceChallengeMethod'), + codeVerifier: stringArgOrNull(values, 'pkceCodeVerifier'), } : null, }); } else if (grantType === 'implicit') { - const authorizationUrl = requiredString(values, 'authorizationUrl'); + const authorizationUrl = stringArg(values, 'authorizationUrl'); token = await getImplicit(ctx, contextId, { authorizationUrl: authorizationUrl.match(/^https?:\/\//) ? authorizationUrl : `https://${authorizationUrl}`, - clientId: requiredString(values, 'clientId'), - redirectUri: optionalString(values, 'redirectUri'), - responseType: requiredString(values, 'responseType'), - scope: optionalString(values, 'scope'), - state: optionalString(values, 'state'), + clientId: stringArg(values, 'clientId'), + redirectUri: stringArgOrNull(values, 'redirectUri'), + responseType: stringArg(values, 'responseType'), + scope: stringArgOrNull(values, 'scope'), + state: stringArgOrNull(values, 'state'), }); } else if (grantType === 'client_credentials') { - const accessTokenUrl = requiredString(values, 'accessTokenUrl'); + const accessTokenUrl = stringArg(values, 'accessTokenUrl'); token = await getClientCredentials(ctx, contextId, { accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`, - clientId: requiredString(values, 'clientId'), - clientSecret: requiredString(values, 'clientSecret'), - scope: optionalString(values, 'scope'), + clientId: stringArg(values, 'clientId'), + clientSecret: stringArg(values, 'clientSecret'), + scope: stringArgOrNull(values, 'scope'), credentialsInBody, }); } else if (grantType === 'password') { - const accessTokenUrl = requiredString(values, 'accessTokenUrl'); + const accessTokenUrl = stringArg(values, 'accessTokenUrl'); token = await getPassword(ctx, contextId, { accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`, - clientId: requiredString(values, 'clientId'), - clientSecret: requiredString(values, 'clientSecret'), - username: requiredString(values, 'username'), - password: requiredString(values, 'password'), - scope: optionalString(values, 'scope'), + clientId: stringArg(values, 'clientId'), + clientSecret: stringArg(values, 'clientSecret'), + username: stringArg(values, 'username'), + password: stringArg(values, 'password'), + scope: stringArgOrNull(values, 'scope'), credentialsInBody, }); } else { @@ -306,14 +306,14 @@ export const plugin: PluginDefinition = { }, }; -function optionalString(values: Record, name: string): string | null { +function stringArgOrNull(values: Record, name: string): string | null { const arg = values[name]; if (arg == null || arg == '') return null; return `${arg}`; } -function requiredString(values: Record, name: string): string { - const arg = optionalString(values, name); - if (!arg) throw new Error(`Missing required argument ${name}`); +function stringArg(values: Record, name: string): string { + const arg = stringArgOrNull(values, name); + if (!arg) return ''; return arg; } From abea5e6b5da3fbfebdd1b9a5a7a4901be4ef100c Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 21 Feb 2025 14:02:41 -0800 Subject: [PATCH 062/996] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 276dc8a77..d5a0cf5a2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ # Yaak Plugins This repository contains all the Yaak plugins that are bundled within the application (can't be uninstalled). + +## Feedback and Bug Reports + +All feedback, bug reports, questions, and feature requests should be reported to +[feedback.yaak.app](https://feedback.yaak.app). From a0e196a9e76f230cb4404104c121437c47e039ad Mon Sep 17 00:00:00 2001 From: Hao Xiang Date: Sat, 22 Feb 2025 23:00:04 +0800 Subject: [PATCH 063/996] adding alternate key combinations for special shift (#173) --- src-web/hooks/useHotKey.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src-web/hooks/useHotKey.ts b/src-web/hooks/useHotKey.ts index 6080a8f31..54e1da4ff 100644 --- a/src-web/hooks/useHotKey.ts +++ b/src-web/hooks/useHotKey.ts @@ -1,8 +1,8 @@ import { type } from '@tauri-apps/plugin-os'; +import { debounce } from '@yaakapp-internal/lib'; import { useEffect, useRef } from 'react'; import { capitalize } from '../lib/capitalize'; import { useOsInfo } from './useOsInfo'; -import { debounce } from '@yaakapp-internal/lib'; const HOLD_KEYS = ['Shift', 'Control', 'Command', 'Alt', 'Meta']; @@ -31,9 +31,9 @@ const hotkeys: Record = { 'app.zoom_out': ['CmdCtrl+-'], 'app.zoom_reset': ['CmdCtrl+0'], 'command_palette.toggle': ['CmdCtrl+k'], - 'environmentEditor.toggle': ['CmdCtrl+Shift+e'], + 'environmentEditor.toggle': ['CmdCtrl+Shift+E', 'CmdCtrl+Shift+e'], 'grpc_request.send': ['CmdCtrl+Enter', 'CmdCtrl+r'], - 'hotkeys.showHelp': ['CmdCtrl+Shift+/'], + 'hotkeys.showHelp': ['CmdCtrl+Shift+/', 'CmdCtrl+Shift+?'], // when shift is pressed, it might be a question mark 'http_request.create': ['CmdCtrl+n'], 'http_request.delete': ['Backspace'], 'http_request.duplicate': ['CmdCtrl+d'], @@ -115,6 +115,7 @@ export function useHotKey( if (e.metaKey) currentKeysWithModifiers.add('Meta'); if (e.shiftKey) currentKeysWithModifiers.add('Shift'); + console.log('down', currentKeysWithModifiers); for (const [hkAction, hkKeys] of Object.entries(hotkeys) as [HotkeyAction, string[]][]) { if ( (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) && From efe4eef1b70fc2d332c62df595f8a363c53a8d80 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 23 Feb 2025 06:05:01 -0800 Subject: [PATCH 064/996] Fix deleting selected environment --- src-web/components/EnvironmentEditDialog.tsx | 28 +++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src-web/components/EnvironmentEditDialog.tsx b/src-web/components/EnvironmentEditDialog.tsx index 7618099bc..c84a97d8e 100644 --- a/src-web/components/EnvironmentEditDialog.tsx +++ b/src-web/components/EnvironmentEditDialog.tsx @@ -32,10 +32,13 @@ export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) { const { baseEnvironment, subEnvironments, allEnvironments } = useEnvironments(); const [selectedEnvironmentId, setSelectedEnvironmentId] = useState( - initialEnvironment?.id ?? baseEnvironment?.id ?? null, + initialEnvironment?.id ?? null, ); - const selectedEnvironment = allEnvironments.find((e) => e.id === selectedEnvironmentId); + const selectedEnvironment = + selectedEnvironmentId != null + ? allEnvironments.find((e) => e.id === selectedEnvironmentId) + : baseEnvironment; const handleCreateEnvironment = async () => { if (baseEnvironment == null) return; @@ -55,7 +58,7 @@ export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) {
setSelectedEnvironmentId(baseEnvironment?.id ?? null)} + onClick={() => setSelectedEnvironmentId(null)} environment={null} rightSlot={ setSelectedEnvironmentId(e.id)} + onDelete={() => { + if (e.id === selectedEnvironmentId) { + setSelectedEnvironmentId(null); + } + }} > {e.name} @@ -90,11 +98,7 @@ export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) { )} secondSlot={() => - selectedEnvironmentId == null ? ( -
- No selected environment -
- ) : selectedEnvironment == null ? ( + selectedEnvironment == null ? (
Failed to find selected environment {selectedEnvironmentId} @@ -198,6 +202,7 @@ function SidebarButton({ className, active, onClick, + onDelete, rightSlot, environment, }: { @@ -205,6 +210,7 @@ function SidebarButton({ children: ReactNode; active: boolean; onClick: () => void; + onDelete?: () => void; rightSlot?: ReactNode; environment: Environment | null; }) { @@ -275,7 +281,11 @@ function SidebarButton({ color: 'danger', label: 'Delete', leftSlot: , - onSelect: () => deleteEnvironment.mutate(), + onSelect: () => { + deleteEnvironment.mutate(undefined, { + onSuccess: onDelete, + }); + }, }, ]} /> From 95c12ad291c379bd81a3b109a41eafc6410b776c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 23 Feb 2025 06:09:26 -0800 Subject: [PATCH 065/996] Bump openssl from 0.10.66 to 0.10.70 in /src-tauri (#161) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src-tauri/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 2d289e7ce..ea1796d6d 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3513,9 +3513,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6" dependencies = [ "bitflags 2.6.0", "cfg-if", From 9d8b7a52657f7cb478b28afdebe28a09603bcbc7 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 23 Feb 2025 06:25:53 -0800 Subject: [PATCH 066/996] Tweak getting content type --- src-web/components/ConfirmLargeResponse.tsx | 4 ++-- src-web/components/HttpRequestPane.tsx | 5 ++--- src-web/components/HttpResponsePane.tsx | 4 ++-- src-web/components/responseViewers/BinaryViewer.tsx | 4 ++-- src-web/components/responseViewers/HTMLOrTextViewer.tsx | 8 +++----- src-web/hooks/useContentTypeFromHeaders.ts | 9 --------- src-web/hooks/useSaveResponse.tsx | 6 +++--- src-web/lib/model_util.ts | 6 +++--- 8 files changed, 17 insertions(+), 29 deletions(-) delete mode 100644 src-web/hooks/useContentTypeFromHeaders.ts diff --git a/src-web/components/ConfirmLargeResponse.tsx b/src-web/components/ConfirmLargeResponse.tsx index e1d6fd558..973ed6e12 100644 --- a/src-web/components/ConfirmLargeResponse.tsx +++ b/src-web/components/ConfirmLargeResponse.tsx @@ -3,7 +3,7 @@ import { useMemo, type ReactNode } from 'react'; import { useSaveResponse } from '../hooks/useSaveResponse'; import { useToggle } from '../hooks/useToggle'; import { isProbablyTextContentType } from '../lib/contentType'; -import { getContentTypeHeader } from '../lib/model_util'; +import { getContentTypeFromHeaders } from '../lib/model_util'; import { getResponseBodyText } from '../lib/responseBody'; import { CopyButton } from './CopyButton'; import { Banner } from './core/Banner'; @@ -24,7 +24,7 @@ export function ConfirmLargeResponse({ children, response }: Props) { const { mutate: saveResponse } = useSaveResponse(response); const [showLargeResponse, toggleShowLargeResponse] = useToggle(); const isProbablyText = useMemo(() => { - const contentType = getContentTypeHeader(response.headers); + const contentType = getContentTypeFromHeaders(response.headers); return isProbablyTextContentType(contentType); }, [response.headers]); diff --git a/src-web/components/HttpRequestPane.tsx b/src-web/components/HttpRequestPane.tsx index f8a201dca..c578a5793 100644 --- a/src-web/components/HttpRequestPane.tsx +++ b/src-web/components/HttpRequestPane.tsx @@ -7,7 +7,6 @@ import type { CSSProperties } from 'react'; import React, { useCallback, useMemo, useState } from 'react'; import { activeRequestIdAtom } from '../hooks/useActiveRequestId'; import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse'; -import { useContentTypeFromHeaders } from '../hooks/useContentTypeFromHeaders'; import { grpcRequestsAtom } from '../hooks/useGrpcRequests'; import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication'; import { httpRequestsAtom } from '../hooks/useHttpRequests'; @@ -28,7 +27,7 @@ import { BODY_TYPE_JSON, BODY_TYPE_NONE, BODY_TYPE_OTHER, - BODY_TYPE_XML, + BODY_TYPE_XML, getContentTypeFromHeaders, } from '../lib/model_util'; import { prepareImportQuerystring } from '../lib/prepareImportQuerystring'; import { resolvedModelName } from '../lib/resolvedModelName'; @@ -84,7 +83,7 @@ export function HttpRequestPane({ style, fullHeight, className, activeRequest }: const [forceUpdateHeaderEditorKey, setForceUpdateHeaderEditorKey] = useState(0); const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null); const [{ urlKey }, { focusParamsTab, forceUrlRefresh, forceParamsRefresh }] = useRequestEditor(); - const contentType = useContentTypeFromHeaders(activeRequest.headers); + const contentType = getContentTypeFromHeaders(activeRequest.headers); const authentication = useHttpAuthenticationSummaries(); const handleContentTypeChange = useCallback( diff --git a/src-web/components/HttpResponsePane.tsx b/src-web/components/HttpResponsePane.tsx index 217b7244c..8f9c32458 100644 --- a/src-web/components/HttpResponsePane.tsx +++ b/src-web/components/HttpResponsePane.tsx @@ -3,9 +3,9 @@ import classNames from 'classnames'; import type { CSSProperties, ReactNode } from 'react'; import React, { useCallback, useMemo } from 'react'; import { useLocalStorage } from 'react-use'; -import { useContentTypeFromHeaders } from '../hooks/useContentTypeFromHeaders'; import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse'; import { useResponseViewMode } from '../hooks/useResponseViewMode'; +import { getContentTypeFromHeaders } from '../lib/model_util'; import { ConfirmLargeResponse } from './ConfirmLargeResponse'; import { Banner } from './core/Banner'; import { CountBadge } from './core/CountBadge'; @@ -47,7 +47,7 @@ export function HttpResponsePane({ style, className, activeRequestId }: Props) { 'responsePaneActiveTabs', {}, ); - const contentType = useContentTypeFromHeaders(activeResponse?.headers ?? null); + const contentType = getContentTypeFromHeaders(activeResponse?.headers ?? null); const tabs = useMemo( () => [ diff --git a/src-web/components/responseViewers/BinaryViewer.tsx b/src-web/components/responseViewers/BinaryViewer.tsx index 50cf269a8..96aa4fe1b 100644 --- a/src-web/components/responseViewers/BinaryViewer.tsx +++ b/src-web/components/responseViewers/BinaryViewer.tsx @@ -1,6 +1,6 @@ import type { HttpResponse } from '@yaakapp-internal/models'; import { useSaveResponse } from '../../hooks/useSaveResponse'; -import { getContentTypeHeader } from '../../lib/model_util'; +import { getContentTypeFromHeaders } from '../../lib/model_util'; import { Banner } from '../core/Banner'; import { Button } from '../core/Button'; import { InlineCode } from '../core/InlineCode'; @@ -13,7 +13,7 @@ interface Props { export function BinaryViewer({ response }: Props) { const saveResponse = useSaveResponse(response); - const contentType = getContentTypeHeader(response.headers) ?? 'unknown'; + const contentType = getContentTypeFromHeaders(response.headers) ?? 'unknown'; // Wait until the response has been fully-downloaded if (response.state === 'closed') { diff --git a/src-web/components/responseViewers/HTMLOrTextViewer.tsx b/src-web/components/responseViewers/HTMLOrTextViewer.tsx index 75a78ba93..b379f2181 100644 --- a/src-web/components/responseViewers/HTMLOrTextViewer.tsx +++ b/src-web/components/responseViewers/HTMLOrTextViewer.tsx @@ -1,7 +1,7 @@ import type { HttpResponse } from '@yaakapp-internal/models'; -import { useContentTypeFromHeaders } from '../../hooks/useContentTypeFromHeaders'; import { useResponseBodyText } from '../../hooks/useResponseBodyText'; import { languageFromContentType } from '../../lib/contentType'; +import { getContentTypeFromHeaders } from '../../lib/model_util'; import { BinaryViewer } from './BinaryViewer'; import { TextViewer } from './TextViewer'; import { WebPageViewer } from './WebPageViewer'; @@ -14,10 +14,8 @@ interface Props { export function HTMLOrTextViewer({ response, pretty, textViewerClassName }: Props) { const rawTextBody = useResponseBodyText(response); - const language = languageFromContentType( - useContentTypeFromHeaders(response.headers), - rawTextBody.data ?? '', - ); + const contentType = getContentTypeFromHeaders(response.headers); + const language = languageFromContentType(contentType, rawTextBody.data ?? ''); if (rawTextBody.isLoading || response.state === 'initialized') { return null; diff --git a/src-web/hooks/useContentTypeFromHeaders.ts b/src-web/hooks/useContentTypeFromHeaders.ts deleted file mode 100644 index 1f7c500d9..000000000 --- a/src-web/hooks/useContentTypeFromHeaders.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { HttpResponseHeader } from '@yaakapp-internal/models'; -import { useMemo } from 'react'; - -export function useContentTypeFromHeaders(headers: HttpResponseHeader[] | null): string | null { - return useMemo( - () => headers?.find((h) => h.name.toLowerCase() === 'content-type')?.value ?? null, - [headers], - ); -} diff --git a/src-web/hooks/useSaveResponse.tsx b/src-web/hooks/useSaveResponse.tsx index 8d6e41a20..8f54518a1 100644 --- a/src-web/hooks/useSaveResponse.tsx +++ b/src-web/hooks/useSaveResponse.tsx @@ -3,7 +3,7 @@ import type { HttpResponse } from '@yaakapp-internal/models'; import mime from 'mime'; import slugify from 'slugify'; import { InlineCode } from '../components/core/InlineCode'; -import { getContentTypeHeader } from '../lib/model_util'; +import { getContentTypeFromHeaders } from '../lib/model_util'; import { invokeCmd } from '../lib/tauri'; import { showToast } from '../lib/toast'; import { useFastMutation } from './useFastMutation'; @@ -13,10 +13,10 @@ export function useSaveResponse(response: HttpResponse) { return useFastMutation({ mutationKey: ['save_response', response.id], mutationFn: async () => { - const request = await getHttpRequest(response.requestId); + const request = getHttpRequest(response.requestId); if (request == null) return null; - const contentType = getContentTypeHeader(response.headers) ?? 'unknown'; + const contentType = getContentTypeFromHeaders(response.headers) ?? 'unknown'; const ext = mime.getExtension(contentType); const slug = slugify(request.name || 'response', { lower: true }); const filepath = await save({ diff --git a/src-web/lib/model_util.ts b/src-web/lib/model_util.ts index fb82f210f..b0cd59d87 100644 --- a/src-web/lib/model_util.ts +++ b/src-web/lib/model_util.ts @@ -36,12 +36,12 @@ export function modelsEq(a: AnyModel, b: AnyModel) { return false; } -export function getContentTypeHeader(headers: HttpResponseHeader[]): string | null { - return headers.find((h) => h.name.toLowerCase() === 'content-type')?.value ?? null; +export function getContentTypeFromHeaders(headers: HttpResponseHeader[] | null): string | null { + return headers?.find((h) => h.name.toLowerCase() === 'content-type')?.value ?? null; } export function getCharsetFromContentType(headers: HttpResponseHeader[]): string | null { - const contentType = getContentTypeHeader(headers); + const contentType = getContentTypeFromHeaders(headers); if (contentType == null) return null; const mimeType = getMimeTypeFromContentType(contentType); From af7782c93bf7fbadec3267f97271729219e1eb58 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 24 Feb 2025 05:59:15 -0800 Subject: [PATCH 067/996] Better license flows --- src-tauri/Cargo.lock | 94 +++++++++++++++---- src-tauri/Cargo.toml | 2 +- src-web/components/GitDropdown.tsx | 4 +- src-web/components/LicenseBadge.tsx | 40 +++++--- .../components/Settings/SettingsLicense.tsx | 62 ++++++++---- src-web/components/SettingsDropdown.tsx | 2 +- src-web/components/core/Dropdown.tsx | 34 ++++--- src-web/hooks/useHotKey.ts | 1 - src-web/hooks/useLicenseConfirmation.ts | 15 +++ 9 files changed, 184 insertions(+), 70 deletions(-) create mode 100644 src-web/hooks/useLicenseConfirmation.ts diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index ea1796d6d..003ca0f54 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -514,6 +514,25 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "block2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e58aa60e59d8dbfcc36138f5f18be5f24394d33b38b24f7fd0b1caa33095f22f" +dependencies = [ + "block-sys", + "objc2", +] + [[package]] name = "block2" version = "0.5.1" @@ -2420,6 +2439,16 @@ dependencies = [ "png", ] +[[package]] +name = "icrate" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb69199826926eb864697bddd27f73d9fddcffc004f5733131e15b465e30642" +dependencies = [ + "block2 0.4.0", + "objc2", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -3292,7 +3321,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ "bitflags 2.6.0", - "block2", + "block2 0.5.1", "libc", "objc2", "objc2-core-data", @@ -3308,7 +3337,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ "bitflags 2.6.0", - "block2", + "block2 0.5.1", "objc2", "objc2-core-location", "objc2-foundation", @@ -3320,7 +3349,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ - "block2", + "block2 0.5.1", "objc2", "objc2-foundation", ] @@ -3332,7 +3361,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.6.0", - "block2", + "block2 0.5.1", "objc2", "objc2-foundation", ] @@ -3343,7 +3372,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2", + "block2 0.5.1", "objc2", "objc2-foundation", "objc2-metal", @@ -3355,7 +3384,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ - "block2", + "block2 0.5.1", "objc2", "objc2-contacts", "objc2-foundation", @@ -3374,7 +3403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.6.0", - "block2", + "block2 0.5.1", "dispatch", "libc", "objc2", @@ -3386,7 +3415,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ - "block2", + "block2 0.5.1", "objc2", "objc2-app-kit", "objc2-foundation", @@ -3399,8 +3428,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.6.0", - "block2", + "block2 0.5.1", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-osa-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6788b04a18ea31e3dc3ab256b8546639e5bbae07c1a0dc4ea8615252bc6aee9a" +dependencies = [ + "bitflags 2.6.0", "objc2", + "objc2-app-kit", "objc2-foundation", ] @@ -3411,7 +3452,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.6.0", - "block2", + "block2 0.5.1", "objc2", "objc2-foundation", "objc2-metal", @@ -3434,7 +3475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ "bitflags 2.6.0", - "block2", + "block2 0.5.1", "objc2", "objc2-cloud-kit", "objc2-core-data", @@ -3454,7 +3495,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ - "block2", + "block2 0.5.1", "objc2", "objc2-foundation", ] @@ -3466,7 +3507,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ "bitflags 2.6.0", - "block2", + "block2 0.5.1", "objc2", "objc2-core-location", "objc2-foundation", @@ -3479,7 +3520,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68bc69301064cebefc6c4c90ce9cba69225239e4b8ff99d445a2b5563797da65" dependencies = [ "bitflags 2.6.0", - "block2", + "block2 0.5.1", "objc2", "objc2-app-kit", "objc2-foundation", @@ -3611,6 +3652,20 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "osakit" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35366a452fce3f8947eb2f33226a133aaf0cacedef2af67ade348d58be7f85d0" +dependencies = [ + "icrate", + "objc2-foundation", + "objc2-osa-kit", + "serde", + "serde_json", + "thiserror 1.0.63", +] + [[package]] name = "pad" version = "0.1.6" @@ -4513,7 +4568,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8af382a047821a08aa6bfc09ab0d80ff48d45d8726f7cd8e44891f7cb4a4278e" dependencies = [ "ashpd", - "block2", + "block2 0.5.1", "glib-sys", "gobject-sys", "gtk-sys", @@ -5980,17 +6035,18 @@ dependencies = [ [[package]] name = "tauri-plugin-updater" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad3de2b9203bb00b9765e637a9878aaace34df40ae484878b8cea7a5bd5f9188" +checksum = "ebf3da08c36fb03c98c76e5563d4e74d9a590df0f40978cbe07f39cb52833f7c" dependencies = [ "base64 0.22.1", - "dirs 5.0.1", + "dirs 6.0.0", "flate2", "futures-util", "http", "infer", "minisign-verify", + "osakit", "percent-encoding", "reqwest", "semver", @@ -7544,7 +7600,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e644bf458e27b11b0ecafc9e5633d1304fdae82baca1d42185669752fe6ca4f" dependencies = [ "base64 0.22.1", - "block2", + "block2 0.5.1", "cookie", "crossbeam-channel", "dpi", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 08d864f5c..5b9c4bc62 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -67,7 +67,7 @@ tauri-plugin-opener = "2.2.5" tauri-plugin-os = "2.2.0" tauri-plugin-shell = { workspace = true } tauri-plugin-single-instance = "2.2.1" -tauri-plugin-updater = "2.4.0" +tauri-plugin-updater = "2.5.0" tauri-plugin-window-state = "2.2.1" tokio = { version = "1.43.0", features = ["sync"] } tokio-stream = "0.1.17" diff --git a/src-web/components/GitDropdown.tsx b/src-web/components/GitDropdown.tsx index 059ed2dad..83d6f1980 100644 --- a/src-web/components/GitDropdown.tsx +++ b/src-web/components/GitDropdown.tsx @@ -336,12 +336,14 @@ function SetupSyncDropdown({ workspaceMeta }: { workspaceMeta: WorkspaceMeta }) label: banner, }, { + color: 'success', label: 'Open Workspace Settings', leftSlot: , onSelect() { openWorkspaceSettings.mutate({ openSyncMenu: true }); }, }, + { type: 'separator' }, { label: 'Hide This Message', leftSlot: , @@ -396,8 +398,8 @@ function SetupGitDropdown({ leftSlot: , onSelect: initRepo, }, + { type: 'separator' }, { - color: 'warning', label: 'Hide This Message', leftSlot: , async onSelect() { diff --git a/src-web/components/LicenseBadge.tsx b/src-web/components/LicenseBadge.tsx index 06dfedc60..45ca9057c 100644 --- a/src-web/components/LicenseBadge.tsx +++ b/src-web/components/LicenseBadge.tsx @@ -1,14 +1,14 @@ -import { openUrl } from '@tauri-apps/plugin-opener'; import type { LicenseCheckStatus } from '@yaakapp-internal/license'; import { useLicense } from '@yaakapp-internal/license'; import type { ReactNode } from 'react'; +import { openSettings } from '../commands/openSettings'; import { appInfo } from '../hooks/useAppInfo'; +import { useLicenseConfirmation } from '../hooks/useLicenseConfirmation'; import type { ButtonProps } from './core/Button'; import { Button } from './core/Button'; import { Icon } from './core/Icon'; import { HStack } from './core/Stacks'; -import { openSettings } from '../commands/openSettings'; -import {SettingsTab} from "./Settings/SettingsTab"; +import { SettingsTab } from './Settings/SettingsTab'; const details: Record< LicenseCheckStatus['type'] | 'dev' | 'beta', @@ -26,22 +26,30 @@ const details: Record< dev: { label: 'Develop', color: 'secondary' }, commercial_use: null, invalid_license: { label: 'License Error', color: 'danger' }, - personal_use: { label: 'Personal Use', color: 'primary' }, - trialing: { label: 'Personal Use', color: 'primary' }, + personal_use: { label: 'Personal Use', color: 'success' }, + trialing: { label: 'Active Trial', color: 'success' }, }; export function LicenseBadge() { const { check } = useLicense(); + const [licenseDetails, setLicenseDetails] = useLicenseConfirmation(); + + // Hasn't loaded yet + if (licenseDetails == null || check.data == null) { + return null; + } + + // User has confirmed they are using Yaak for personal use only, so hide badge + if (licenseDetails.confirmedPersonalUse) { + return null; + } - if (check.data == null) { + // User is trialing but has already seen the message, so hide badge + if (check.data.type === 'trialing' && licenseDetails.hasDismissedTrial) { return null; } - const checkType = appInfo.version.includes('beta') - ? 'beta' - : appInfo.isDev - ? 'dev' - : check.data.type; + const checkType = appInfo.version.includes('beta') ? 'beta' : check.data.type; const detail = details[checkType]; if (detail == null) { return null; @@ -53,11 +61,13 @@ export function LicenseBadge() { variant="border" className="!rounded-full mx-1" onClick={async () => { - if (checkType === 'beta') { - await openUrl('https://feedback.yaak.app'); - } else { - openSettings.mutate(SettingsTab.License); + if (check.data.type === 'trialing') { + await setLicenseDetails((v) => ({ + ...v, + dismissedTrial: true, + })); } + openSettings.mutate(SettingsTab.License); }} color={detail.color} event={{ id: 'license-badge', status: check.data.type }} diff --git a/src-web/components/Settings/SettingsLicense.tsx b/src-web/components/Settings/SettingsLicense.tsx index 7d57d40b8..9cb58c901 100644 --- a/src-web/components/Settings/SettingsLicense.tsx +++ b/src-web/components/Settings/SettingsLicense.tsx @@ -1,47 +1,75 @@ +import { openUrl } from '@tauri-apps/plugin-opener'; import { useLicense } from '@yaakapp-internal/license'; import { formatDistanceToNowStrict } from 'date-fns'; import React, { useState } from 'react'; +import { useLicenseConfirmation } from '../../hooks/useLicenseConfirmation'; import { useToggle } from '../../hooks/useToggle'; import { Banner } from '../core/Banner'; import { Button } from '../core/Button'; +import { Checkbox } from '../core/Checkbox'; import { Icon } from '../core/Icon'; import { Link } from '../core/Link'; import { PlainInput } from '../core/PlainInput'; import { HStack, VStack } from '../core/Stacks'; -import { openUrl } from '@tauri-apps/plugin-opener'; export function SettingsLicense() { const { check, activate } = useLicense(); const [key, setKey] = useState(''); const [activateFormVisible, toggleActivateFormVisible] = useToggle(false); + const [licenseDetails, setLicenseDetails] = useLicenseConfirmation(); + const [checked, setChecked] = useState(false); if (check.isPending) { return null; } return ( -
+
{check.data?.type === 'commercial_use' ? ( License active! Enjoy using Yaak for commercial use. - ) : ( - - {check.data?.type === 'trialing' && ( -

- - You have {formatDistanceToNowStrict(check.data.end)} remaining on your trial. - -

- )} + ) : check.data?.type == 'trialing' ? ( +

- A commercial license is required if using Yaak within a for-profit organization.{' '} - - Learn More - + {formatDistanceToNowStrict(check.data.end)} days remaining on your + commercial use trial

- )} + ) : check.data?.type == 'personal_use' && !licenseDetails?.confirmedPersonalUse ? ( + +

+ Your 30-day trial has ended. Please activate a license or confirm how you're using + Yaak. +

+
{ + e.preventDefault(); + await setLicenseDetails((v) => ({ + ...v, + confirmedPersonalUse: true, + })); + }} + > + + + +
+ ) : null} + +

+ A commercial license is required if using Yaak within a for-profit organization.{' '} + + Learn More + +

{check.error && {check.error}} {activate.error && {activate.error}} @@ -80,7 +108,7 @@ export function SettingsLicense() { diff --git a/src-web/components/MarkdownEditor.tsx b/src-web/components/MarkdownEditor.tsx index 955487fe4..0caa682f5 100644 --- a/src-web/components/MarkdownEditor.tsx +++ b/src-web/components/MarkdownEditor.tsx @@ -66,18 +66,8 @@ export function MarkdownEditor({ onChange={setViewMode} value={viewMode} options={[ - { - event: { id: 'md_mode', mode: 'preview' }, - icon: 'eye', - label: 'Preview mode', - value: 'preview', - }, - { - event: { id: 'md_mode', mode: 'edit' }, - icon: 'pencil', - label: 'Edit mode', - value: 'edit', - }, + { icon: 'eye', label: 'Preview mode', value: 'preview' }, + { icon: 'pencil', label: 'Edit mode', value: 'edit' }, ]} />
diff --git a/src-web/components/Settings/SettingsAppearance.tsx b/src-web/components/Settings/SettingsAppearance.tsx index 54bc10ffb..18ae55155 100644 --- a/src-web/components/Settings/SettingsAppearance.tsx +++ b/src-web/components/Settings/SettingsAppearance.tsx @@ -96,7 +96,6 @@ export function SettingsAppearance() { value={`${settings.interfaceFontSize}`} options={fontSizeOptions} onChange={(v) => updateSettings.mutate({ interfaceFontSize: parseInt(v) })} - event="ui-font-size" /> updateSettings.mutate({ editorKeymap: v })} - event="editor-keymap" /> updateSettings.mutate({ editorSoftWrap })} - event="editor-wrap-lines" /> @@ -134,7 +130,6 @@ export function SettingsAppearance() { size="sm" value={settings.appearance} onChange={(appearance) => updateSettings.mutate({ appearance })} - event="appearance" options={[ { label: 'Automatic', value: 'system' }, { label: 'Light', value: 'light' }, @@ -152,7 +147,6 @@ export function SettingsAppearance() { className="flex-1" value={activeTheme.light.id} options={lightThemes} - event="theme.light" onChange={(themeLight) => updateSettings.mutate({ ...settings, themeLight })} /> )} @@ -166,7 +160,6 @@ export function SettingsAppearance() { size="sm" value={activeTheme.dark.id} options={darkThemes} - event="theme.dark" onChange={(themeDark) => updateSettings.mutate({ ...settings, themeDark })} /> )} diff --git a/src-web/components/Settings/SettingsGeneral.tsx b/src-web/components/Settings/SettingsGeneral.tsx index 296a31249..18a5e17f5 100644 --- a/src-web/components/Settings/SettingsGeneral.tsx +++ b/src-web/components/Settings/SettingsGeneral.tsx @@ -38,7 +38,6 @@ export function SettingsGeneral() { size="sm" value={settings.updateChannel} onChange={(updateChannel) => updateSettings.mutate({ updateChannel })} - event="update-channel" options={[ { label: 'Stable (less frequent)', value: 'stable' }, { label: 'Beta (more frequent)', value: 'beta' }, @@ -59,7 +58,6 @@ export function SettingsGeneral() { labelPosition="left" labelClassName="w-[14rem]" size="sm" - event="workspace-switch-behavior" value={ settings.openWorkspaceNewWindow === true ? 'new' @@ -81,9 +79,9 @@ export function SettingsGeneral() { updateSettings.mutate({ telemetry })} /> @@ -115,7 +113,6 @@ export function SettingsGeneral() { upsertWorkspace.mutate({ ...workspace, settingValidateCertificates }) } @@ -124,7 +121,6 @@ export function SettingsGeneral() { upsertWorkspace.mutate({ ...workspace, diff --git a/src-web/components/Settings/SettingsLicense.tsx b/src-web/components/Settings/SettingsLicense.tsx index 9cb58c901..e88760efa 100644 --- a/src-web/components/Settings/SettingsLicense.tsx +++ b/src-web/components/Settings/SettingsLicense.tsx @@ -81,7 +81,6 @@ export function SettingsLicense() { color="secondary" size="sm" onClick={toggleActivateFormVisible} - event="license.another" > Activate Another License @@ -90,7 +89,6 @@ export function SettingsLicense() { size="sm" onClick={() => openUrl('https://yaak.app/dashboard')} rightSlot={} - event="license.support" > Direct Support @@ -101,7 +99,6 @@ export function SettingsLicense() { color="primary" size="sm" onClick={toggleActivateFormVisible} - event="license.activate" > Activate @@ -110,7 +107,6 @@ export function SettingsLicense() { size="sm" onClick={() => openUrl('https://yaak.app/pricing?ref=app.yaak.desktop')} rightSlot={} - event="license.purchase" > Purchase @@ -140,7 +136,6 @@ export function SettingsLicense() { color="primary" size="sm" isLoading={activate.isPending} - event="license.submit" > Submit diff --git a/src-web/components/Settings/SettingsPlugins.tsx b/src-web/components/Settings/SettingsPlugins.tsx index 10bf1236c..9869bf1ae 100644 --- a/src-web/components/Settings/SettingsPlugins.tsx +++ b/src-web/components/Settings/SettingsPlugins.tsx @@ -66,7 +66,6 @@ export function SettingsPlugins() { type="submit" color="primary" className="ml-auto" - event="plugin.add" > Add Plugin @@ -76,14 +75,12 @@ export function SettingsPlugins() { icon="refresh" title="Reload plugins" spin={refreshPlugins.isPending} - event="plugin.reload" onClick={() => refreshPlugins.mutate()} /> openUrl('https://feedback.yaak.app/help/articles/6911763-quick-start')} /> @@ -107,7 +104,6 @@ function PluginInfo({ plugin }: { plugin: Plugin }) { size="sm" icon="trash" title="Uninstall plugin" - event="plugin.delete" onClick={() => deletePlugin.mutate()} /> diff --git a/src-web/components/Settings/SettingsProxy.tsx b/src-web/components/Settings/SettingsProxy.tsx index 7b5b58f0a..8409c03d5 100644 --- a/src-web/components/Settings/SettingsProxy.tsx +++ b/src-web/components/Settings/SettingsProxy.tsx @@ -19,7 +19,6 @@ export function SettingsProxy() { hideLabel size="sm" value={settings.proxy?.type ?? 'automatic'} - event="proxy" onChange={(v) => { if (v === 'automatic') { updateSettings.mutate({ proxy: undefined }); diff --git a/src-web/components/WebsocketRequestPane.tsx b/src-web/components/WebsocketRequestPane.tsx index 7b9c5e869..58acdd630 100644 --- a/src-web/components/WebsocketRequestPane.tsx +++ b/src-web/components/WebsocketRequestPane.tsx @@ -18,7 +18,6 @@ import { requestsAtom } from '../hooks/useRequests'; import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey'; import { useUpdateAnyHttpRequest } from '../hooks/useUpdateAnyHttpRequest'; import { useLatestWebsocketConnection } from '../hooks/useWebsocketConnections'; -import { trackEvent } from '../lib/analytics'; import { deepEqualAtom } from '../lib/atoms'; import { languageFromContentType } from '../lib/contentType'; import { generateId } from '../lib/generateId'; @@ -190,7 +189,6 @@ export function WebsocketRequestPane({ style, fullHeight, className, activeReque environmentId: getActiveEnvironment()?.id ?? null, cookieJarId: getActiveCookieJar()?.id ?? null, }); - trackEvent('websocket_request', 'send'); }, [activeRequest.id]); const handleSend = useCallback(async () => { @@ -199,13 +197,11 @@ export function WebsocketRequestPane({ style, fullHeight, className, activeReque connectionId: connection?.id, environmentId: getActiveEnvironment()?.id ?? null, }); - trackEvent('websocket_connection', 'send'); }, [connection]); const handleCancel = useCallback(async () => { if (connection == null) return; await closeWebsocket({ connectionId: connection?.id }); - trackEvent('websocket_connection', 'cancel'); }, [connection]); const handleUrlChange = useCallback( diff --git a/src-web/components/WorkspaceHeader.tsx b/src-web/components/WorkspaceHeader.tsx index b2b85697e..396694246 100644 --- a/src-web/components/WorkspaceHeader.tsx +++ b/src-web/components/WorkspaceHeader.tsx @@ -46,7 +46,6 @@ export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Prop icon="search" title="Search or execute a command" size="sm" - event="search" iconColor="secondary" onClick={togglePalette} /> diff --git a/src-web/components/core/Button.tsx b/src-web/components/core/Button.tsx index fb6fd86b6..c229e87a9 100644 --- a/src-web/components/core/Button.tsx +++ b/src-web/components/core/Button.tsx @@ -4,7 +4,6 @@ import type { HTMLAttributes, ReactNode } from 'react'; import { forwardRef, useImperativeHandle, useRef } from 'react'; import type { HotkeyAction } from '../../hooks/useHotKey'; import { useFormattedHotkey, useHotKey } from '../../hooks/useHotKey'; -import { trackEvent } from '../../lib/analytics'; import { Icon } from './Icon'; import { LoadingIcon } from './LoadingIcon'; @@ -22,7 +21,6 @@ export type ButtonProps = Omit, 'color' | 'onC leftSlot?: ReactNode; rightSlot?: ReactNode; hotkeyAction?: HotkeyAction; - event?: string | { id: string; [attr: string]: number | string }; }; export const Button = forwardRef(function Button( @@ -43,7 +41,6 @@ export const Button = forwardRef(function Button hotkeyAction, title, onClick, - event, ...props }: ButtonProps, ref, @@ -107,12 +104,7 @@ export const Button = forwardRef(function Button type={type} className={classes} disabled={disabled} - onClick={(e) => { - onClick?.(e); - if (event != null) { - trackEvent('button', 'click', typeof event === 'string' ? { id: event } : event); - } - }} + onClick={onClick} onDoubleClick={(e) => { // Kind of a hack? This prevents double-clicks from going through buttons. For example, when // double-clicking the workspace header to toggle window maximization diff --git a/src-web/components/core/Checkbox.tsx b/src-web/components/core/Checkbox.tsx index 487699366..458b4a426 100644 --- a/src-web/components/core/Checkbox.tsx +++ b/src-web/components/core/Checkbox.tsx @@ -1,6 +1,5 @@ import classNames from 'classnames'; import { type ReactNode } from 'react'; -import { trackEvent } from '../../lib/analytics'; import { Icon } from './Icon'; import { HStack } from './Stacks'; @@ -13,7 +12,6 @@ export interface CheckboxProps { inputWrapperClassName?: string; hideLabel?: boolean; fullWidth?: boolean; - event?: string; } export function Checkbox({ @@ -25,7 +23,6 @@ export function Checkbox({ title, hideLabel, fullWidth, - event, }: CheckboxProps) { return ( @@ -42,9 +39,6 @@ export function Checkbox({ disabled={disabled} onChange={() => { onChange(checked === 'indeterminate' ? true : !checked); - if (event != null) { - trackEvent('button', 'click', { id: event, checked: checked ? 'on' : 'off' }); - } }} />
diff --git a/src-web/components/core/Link.tsx b/src-web/components/core/Link.tsx index 6c3c03c29..2e0988ced 100644 --- a/src-web/components/core/Link.tsx +++ b/src-web/components/core/Link.tsx @@ -1,15 +1,13 @@ +import { Link as RouterLink } from '@tanstack/react-router'; import classNames from 'classnames'; import type { HTMLAttributes } from 'react'; -import { Link as RouterLink } from '@tanstack/react-router'; -import { trackEvent } from '../../lib/analytics'; import { Icon } from './Icon'; interface Props extends HTMLAttributes { href: string; - event?: string; } -export function Link({ href, children, className, event, ...other }: Props) { +export function Link({ href, children, className, ...other }: Props) { const isExternal = href.match(/^https?:\/\//); className = classNames(className, 'relative underline hover:text-violet-600'); @@ -23,9 +21,6 @@ export function Link({ href, children, className, event, ...other }: Props) { className={classNames(className, 'pr-4 inline-flex items-center')} onClick={(e) => { e.preventDefault(); - if (event != null) { - trackEvent('link', 'click', { id: event }); - } }} {...other} > diff --git a/src-web/components/core/PairEditor.tsx b/src-web/components/core/PairEditor.tsx index c8a2b675f..fc960b929 100644 --- a/src-web/components/core/PairEditor.tsx +++ b/src-web/components/core/PairEditor.tsx @@ -261,7 +261,6 @@ export const PairEditor = forwardRef(function Pa variant="border" className="m-2" size="xs" - event="pairs.reveal-more" > Show {pairs.length - MAX_INITIAL_PAIRS} More diff --git a/src-web/components/core/SegmentedControl.tsx b/src-web/components/core/SegmentedControl.tsx index 6716026e3..af73b2b9f 100644 --- a/src-web/components/core/SegmentedControl.tsx +++ b/src-web/components/core/SegmentedControl.tsx @@ -2,18 +2,17 @@ import classNames from 'classnames'; import { useRef } from 'react'; import { useStateWithDeps } from '../../hooks/useStateWithDeps'; import type { IconProps } from './Icon'; -import type { IconButtonProps } from './IconButton'; import { IconButton } from './IconButton'; import { HStack } from './Stacks'; interface Props { - options: { value: T; label: string; icon: IconProps['icon']; event?: IconButtonProps['event'] }[]; + options: { value: T; label: string; icon: IconProps['icon'] }[]; onChange: (value: T) => void; value: T; name: string; } -export function SegmentedControl({ value, onChange, options, name }: Props) { +export function SegmentedControl({ value, onChange, options }: Props) { const [selectedValue, setSelectedValue] = useStateWithDeps(value, [value]); const containerRef = useRef(null); return ( @@ -45,14 +44,13 @@ export function SegmentedControl({ value, onChange, options, n { onChange: (value: T) => void; size?: ButtonProps['size']; className?: string; - event?: string; disabled?: boolean; } @@ -38,7 +36,6 @@ export function Select({ leftSlot, onChange, className, - event, size = 'md', }: SelectProps) { const osInfo = useOsInfo(); @@ -48,9 +45,6 @@ export function Select({ const handleChange = (value: T) => { onChange?.(value); - if (event != null) { - trackEvent('select', 'click', { id: event, value }); - } }; return ( diff --git a/src-web/components/core/Tabs/Tabs.tsx b/src-web/components/core/Tabs/Tabs.tsx index 1765a9df0..2f90c4fe6 100644 --- a/src-web/components/core/Tabs/Tabs.tsx +++ b/src-web/components/core/Tabs/Tabs.tsx @@ -1,7 +1,6 @@ import classNames from 'classnames'; import type { ReactNode } from 'react'; import { memo, useEffect, useRef } from 'react'; -import { trackEvent } from '../../../lib/analytics'; import { Icon } from '../Icon'; import type { RadioDropdownProps } from '../RadioDropdown'; import { RadioDropdown } from '../RadioDropdown'; @@ -104,14 +103,7 @@ export function Tabs({ onChange={t.options.onChange} > - + ); } diff --git a/src-web/components/Overlay.tsx b/src-web/components/Overlay.tsx index c1e9390c8..3c81cb2d3 100644 --- a/src-web/components/Overlay.tsx +++ b/src-web/components/Overlay.tsx @@ -1,6 +1,6 @@ import classNames from 'classnames'; import FocusTrap from 'focus-trap-react'; -import { motion } from 'framer-motion'; +import * as m from 'motion/react-m'; import type { ReactNode } from 'react'; import React from 'react'; import { Portal } from './Portal'; @@ -48,7 +48,7 @@ export function Overlay({ {open && ( - )} {children} - + )} diff --git a/src-web/components/Settings/SettingsGeneral.tsx b/src-web/components/Settings/SettingsGeneral.tsx index 18a5e17f5..811ed4037 100644 --- a/src-web/components/Settings/SettingsGeneral.tsx +++ b/src-web/components/Settings/SettingsGeneral.tsx @@ -82,7 +82,7 @@ export function SettingsGeneral() { checked={false} title="Send Usage Statistics (all tracking was removed in 2025.1.2)" disabled - onChange={(telemetry) => updateSettings.mutate({ telemetry })} + onChange={() => {}} /> diff --git a/src-web/components/Toasts.tsx b/src-web/components/Toasts.tsx index 292c783a6..ce0f34a9c 100644 --- a/src-web/components/Toasts.tsx +++ b/src-web/components/Toasts.tsx @@ -1,4 +1,4 @@ -import { AnimatePresence } from 'framer-motion'; +import { AnimatePresence } from 'motion/react'; import { useAtomValue } from 'jotai'; import React, { type ReactNode } from 'react'; import { hideToast, toastsAtom } from '../lib/toast'; diff --git a/src-web/components/Workspace.tsx b/src-web/components/Workspace.tsx index 638492e67..9a2d22549 100644 --- a/src-web/components/Workspace.tsx +++ b/src-web/components/Workspace.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import { motion } from 'framer-motion'; +import * as m from 'motion/react-m'; import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react'; import { useCallback, useMemo, useRef, useState } from 'react'; import {duplicateWebsocketRequest} from "../commands/duplicateWebsocketRequest"; @@ -137,7 +137,7 @@ export function Workspace() { portalName="sidebar" onClose={() => setFloatingSidebarHidden(true)} > - - + ) : ( <> diff --git a/src-web/components/core/Dialog.tsx b/src-web/components/core/Dialog.tsx index a0a493f27..ae71e2d25 100644 --- a/src-web/components/core/Dialog.tsx +++ b/src-web/components/core/Dialog.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import { motion } from 'framer-motion'; +import * as m from 'motion/react-m'; import type { ReactNode } from 'react'; import { useMemo } from 'react'; import { useKey } from 'react-use'; @@ -65,7 +65,7 @@ export function Dialog({ aria-labelledby={titleId} aria-describedby={descriptionId} > -
)} - +
); diff --git a/src-web/components/core/Dropdown.tsx b/src-web/components/core/Dropdown.tsx index f3e6982cd..31bbb1175 100644 --- a/src-web/components/core/Dropdown.tsx +++ b/src-web/components/core/Dropdown.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import { motion } from 'framer-motion'; +import * as m from 'motion/react-m'; import { atom } from 'jotai'; import type { CSSProperties, @@ -497,7 +497,7 @@ const Menu = forwardRef - - + )} diff --git a/src-web/components/core/Toast.tsx b/src-web/components/core/Toast.tsx index f73d753eb..a9cde8f19 100644 --- a/src-web/components/core/Toast.tsx +++ b/src-web/components/core/Toast.tsx @@ -1,6 +1,6 @@ import type { ShowToastRequest } from '@yaakapp-internal/plugins'; import classNames from 'classnames'; -import { motion } from 'framer-motion'; +import * as m from 'motion/react-m'; import type { ReactNode } from 'react'; import React from 'react'; import { useKey } from 'react-use'; @@ -45,7 +45,7 @@ export function Toast({ children, open, onClose, timeout, action, icon, color }: const toastIcon = icon ?? (color && color in ICONS && ICONS[color]); return ( - - )}
- + ); } diff --git a/src-web/package.json b/src-web/package.json index c54ff1870..293f2434b 100644 --- a/src-web/package.json +++ b/src-web/package.json @@ -23,10 +23,10 @@ "@replit/codemirror-vim": "^6.2.1", "@replit/codemirror-vscode-keymap": "^6.0.2", "@tailwindcss/container-queries": "^0.1.1", - "@tanstack/react-query": "^5.62.16", - "@tanstack/react-router": "^1.95.1", - "@tanstack/react-virtual": "^3.11.2", - "@tauri-apps/api": "^2.0.1", + "@tanstack/react-query": "^5.66.9", + "@tanstack/react-router": "^1.111.3", + "@tanstack/react-virtual": "^3.13.0", + "@tauri-apps/api": "^2.2.0", "@tauri-apps/plugin-clipboard-manager": "^2.0.0", "@tauri-apps/plugin-dialog": "^2.0.0", "@tauri-apps/plugin-fs": "^2.0.0", @@ -43,7 +43,7 @@ "eventemitter3": "^5.0.1", "focus-trap-react": "^10.2.3", "format-graphql": "^1.5.0", - "framer-motion": "^11.5.4", + "motion": "^12.4.7", "fuzzbunny": "^1.0.1", "hexy": "^0.3.5", "history": "^5.3.0", diff --git a/src-web/routes/__root.tsx b/src-web/routes/__root.tsx index b0ed89aaa..d0b4150ba 100644 --- a/src-web/routes/__root.tsx +++ b/src-web/routes/__root.tsx @@ -1,7 +1,7 @@ import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { createRootRoute, Outlet } from '@tanstack/react-router'; import classNames from 'classnames'; -import { MotionConfig } from 'framer-motion'; +import { domAnimation, LazyMotion, MotionConfig } from 'motion/react'; import { Provider as JotaiProvider } from 'jotai'; import React, { Suspense } from 'react'; import { DndProvider } from 'react-dnd'; @@ -61,25 +61,27 @@ function RouteComponent() { return ( - - - - - - - -
- -
-
-
-
-
+ + + + + + + + +
+ +
+
+
+
+
+
{/**/} {/**/}
diff --git a/src-web/vite.config.ts b/src-web/vite.config.ts index f9ed0513d..ea388ba44 100644 --- a/src-web/vite.config.ts +++ b/src-web/vite.config.ts @@ -27,6 +27,7 @@ export default defineConfig(async () => ({ TanStackRouterVite({ routesDirectory: './routes', generatedRouteTree: './routeTree.gen.ts', + autoCodeSplitting: true, }), svgr(), react(), From c8d61834562d4ff330e719df76cb362a2c7b73b5 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 24 Feb 2025 12:20:47 -0800 Subject: [PATCH 070/996] Reduce plugin runtime memory --- packages/plugin-runtime/package.json | 5 +- packages/plugin-runtime/src/PluginHandle.ts | 44 +- packages/plugin-runtime/src/PluginInstance.ts | 596 ++++++++++++++++++ packages/plugin-runtime/src/index.ts | 8 +- packages/plugin-runtime/src/index.worker.ts | 568 ----------------- src-tauri/src/plugin_events.rs | 2 +- .../plugins/auth-oauth2/build/index.js | 72 ++- .../plugins/exporter-curl/build/index.js | 4 + src-tauri/yaak-plugins/src/manager.rs | 2 +- src-tauri/yaak-plugins/src/plugin_handle.rs | 1 + src-tauri/yaak-sync/index.ts | 6 +- 11 files changed, 660 insertions(+), 648 deletions(-) create mode 100644 packages/plugin-runtime/src/PluginInstance.ts delete mode 100644 packages/plugin-runtime/src/index.worker.ts diff --git a/packages/plugin-runtime/package.json b/packages/plugin-runtime/package.json index f3d80c5b0..39e8aa891 100644 --- a/packages/plugin-runtime/package.json +++ b/packages/plugin-runtime/package.json @@ -3,10 +3,7 @@ "scripts": { "bootstrap": "npm run build", "build": "run-p build:*", - "build:main": "esbuild src/index.ts --bundle --platform=node --outfile=../../src-tauri/vendored/plugin-runtime/index.cjs", - "build:worker": "esbuild src/index.worker.ts --bundle --platform=node --outfile=../../src-tauri/vendored/plugin-runtime/index.worker.cjs", - "build:__main": "esbuild src/index.ts --bundle --platform=node --outfile=../../src-tauri/target/debug/vendored/plugin-runtime/index.cjs", - "build:__worker": "esbuild src/index.ts --bundle --platform=node --outfile=../../src-tauri/target/debug/vendored/plugin-runtime/index.worker.cjs" + "build:main": "esbuild src/index.ts --bundle --platform=node --outfile=../../src-tauri/vendored/plugin-runtime/index.cjs" }, "dependencies": { "ws": "^8.18.0" diff --git a/packages/plugin-runtime/src/PluginHandle.ts b/packages/plugin-runtime/src/PluginHandle.ts index b585c40b3..18dbbdb8f 100644 --- a/packages/plugin-runtime/src/PluginHandle.ts +++ b/packages/plugin-runtime/src/PluginHandle.ts @@ -1,56 +1,28 @@ import type { BootRequest, InternalEvent } from '@yaakapp/api'; -import path from 'node:path'; -import { Worker } from 'node:worker_threads'; import type { EventChannel } from './EventChannel'; -import type { PluginWorkerData } from './index.worker'; +import { PluginInstance, PluginWorkerData } from './PluginInstance'; export class PluginHandle { - #worker: Worker; + #instance: PluginInstance; constructor( readonly pluginRefId: string, readonly bootRequest: BootRequest, - readonly events: EventChannel, + readonly pluginToAppEvents: EventChannel, ) { - this.#worker = this.#createWorker(); - } - - sendToWorker(event: InternalEvent) { - this.#worker.postMessage(event); - } - - async terminate() { - await this.#worker.terminate(); - } - - #createWorker(): Worker { - const workerPath = process.env.YAAK_WORKER_PATH ?? path.join(__dirname, 'index.worker.cjs'); const workerData: PluginWorkerData = { pluginRefId: this.pluginRefId, bootRequest: this.bootRequest, }; - const worker = new Worker(workerPath, { - workerData, - }); - - worker.on('message', (e) => this.events.emit(e)); - worker.on('error', this.#handleError.bind(this)); - worker.on('exit', this.#handleExit.bind(this)); - + this.#instance = new PluginInstance(workerData, pluginToAppEvents); console.log('Created plugin worker for ', this.bootRequest.dir); - - return worker; } - async #handleError(err: Error) { - console.error('Plugin errored', this.bootRequest.dir, err); + sendToWorker(event: InternalEvent) { + this.#instance.postMessage(event); } - async #handleExit(code: number) { - if (code === 0) { - console.log('Plugin exited successfully', this.bootRequest.dir); - } else { - console.log('Plugin exited with status', code, this.bootRequest.dir); - } + terminate() { + this.#instance.terminate(); } } diff --git a/packages/plugin-runtime/src/PluginInstance.ts b/packages/plugin-runtime/src/PluginInstance.ts new file mode 100644 index 000000000..dc9fab322 --- /dev/null +++ b/packages/plugin-runtime/src/PluginInstance.ts @@ -0,0 +1,596 @@ +import type { + BootRequest, + Context, + DeleteKeyValueResponse, + FindHttpResponsesResponse, + FormInput, + GetHttpRequestByIdResponse, + GetKeyValueResponse, + HttpAuthenticationAction, + HttpRequestAction, + InternalEvent, + InternalEventPayload, + JsonPrimitive, + PluginDefinition, + PromptTextResponse, + RenderHttpRequestResponse, + SendHttpRequestResponse, + TemplateFunction, + TemplateRenderResponse, + WindowContext, +} from '@yaakapp/api'; +import console from 'node:console'; +import { readFileSync, type Stats, statSync, watch } from 'node:fs'; +import path from 'node:path'; +// import util from 'node:util'; +import { EventChannel } from './EventChannel'; +// import { interceptStdout } from './interceptStdout'; +import { migrateTemplateFunctionSelectOptions } from './migrations'; + +export interface PluginWorkerData { + bootRequest: BootRequest; + pluginRefId: string; +} + +export class PluginInstance { + #workerData: PluginWorkerData; + #mod: PluginDefinition; + #pkg: { name?: string; version?: string }; + #pluginToAppEvents: EventChannel; + #appToPluginEvents: EventChannel; + + constructor(workerData: PluginWorkerData, pluginEvents: EventChannel) { + this.#workerData = workerData; + this.#pluginToAppEvents = pluginEvents; + this.#appToPluginEvents = new EventChannel(); + + // Forward incoming events to onMessage() + this.#appToPluginEvents.listen(async event => { + await this.#onMessage(event); + }) + + // Reload plugin if the JS or package.json changes + const windowContextNone: WindowContext = { type: 'none' }; + const fileChangeCallback = async () => { + this.#importModule(); + return this.#sendPayload(windowContextNone, { type: 'reload_response' }, null); + }; + + if (this.#workerData.bootRequest.watch) { + watchFile(this.#pathMod(), fileChangeCallback); + watchFile(this.#pathPkg(), fileChangeCallback); + } + + this.#mod = {}; + this.#pkg = JSON.parse(readFileSync(this.#pathPkg(), 'utf8')); + + // TODO: Re-implement this now that we're not using workers + // prefixStdout(`[plugin][${this.#pkg.name}] %s`); + + this.#importModule(); + } + + postMessage(event: InternalEvent) { + this.#appToPluginEvents.emit(event); + } + + terminate() { + this.#unimportModule(); + } + + async #onMessage(event: InternalEvent) { + const ctx = this.#newCtx(event); + + const { windowContext, payload, id: replyId } = event; + try { + if (payload.type === 'boot_request') { + // console.log('Plugin initialized', pkg.name, { capabilities, enableWatch }); + const payload: InternalEventPayload = { + type: 'boot_response', + name: this.#pkg.name ?? 'unknown', + version: this.#pkg.version ?? '0.0.1', + }; + this.#sendPayload(windowContext, payload, replyId); + return; + } + + if (payload.type === 'terminate_request') { + const payload: InternalEventPayload = { + type: 'terminate_response', + }; + this.#sendPayload(windowContext, payload, replyId); + return; + } + + if ( + payload.type === 'import_request' && + typeof this.#mod?.importer?.onImport === 'function' + ) { + const reply = await this.#mod.importer.onImport(ctx, { + text: payload.content, + }); + if (reply != null) { + const replyPayload: InternalEventPayload = { + type: 'import_response', + // deno-lint-ignore no-explicit-any + resources: reply.resources as any, + }; + this.#sendPayload(windowContext, replyPayload, replyId); + return; + } else { + // Continue, to send back an empty reply + } + } + + if (payload.type === 'filter_request' && typeof this.#mod?.filter?.onFilter === 'function') { + const reply = await this.#mod.filter.onFilter(ctx, { + filter: payload.filter, + payload: payload.content, + mimeType: payload.type, + }); + const replyPayload: InternalEventPayload = { + type: 'filter_response', + content: reply.filtered, + }; + this.#sendPayload(windowContext, replyPayload, replyId); + return; + } + + if ( + payload.type === 'get_http_request_actions_request' && + Array.isArray(this.#mod?.httpRequestActions) + ) { + const reply: HttpRequestAction[] = this.#mod.httpRequestActions.map((a) => ({ + ...a, + // Add everything except onSelect + onSelect: undefined, + })); + const replyPayload: InternalEventPayload = { + type: 'get_http_request_actions_response', + pluginRefId: this.#workerData.pluginRefId, + actions: reply, + }; + this.#sendPayload(windowContext, replyPayload, replyId); + return; + } + + if ( + payload.type === 'get_template_functions_request' && + Array.isArray(this.#mod?.templateFunctions) + ) { + const reply: TemplateFunction[] = this.#mod.templateFunctions.map((templateFunction) => { + return { + ...migrateTemplateFunctionSelectOptions(templateFunction), + // Add everything except render + onRender: undefined, + }; + }); + const replyPayload: InternalEventPayload = { + type: 'get_template_functions_response', + pluginRefId: this.#workerData.pluginRefId, + functions: reply, + }; + this.#sendPayload(windowContext, replyPayload, replyId); + return; + } + + if (payload.type === 'get_http_authentication_summary_request' && this.#mod?.authentication) { + const { name, shortLabel, label } = this.#mod.authentication; + const replyPayload: InternalEventPayload = { + type: 'get_http_authentication_summary_response', + name, + label, + shortLabel, + }; + + this.#sendPayload(windowContext, replyPayload, replyId); + return; + } + + if (payload.type === 'get_http_authentication_config_request' && this.#mod?.authentication) { + const { args, actions } = this.#mod.authentication; + const resolvedArgs: FormInput[] = []; + for (let i = 0; i < args.length; i++) { + let v = args[i]; + if ('dynamic' in v) { + const dynamicAttrs = await v.dynamic(ctx, payload); + const { dynamic, ...other } = v; + resolvedArgs.push({ ...other, ...dynamicAttrs } as FormInput); + } else { + resolvedArgs.push(v); + } + } + const resolvedActions: HttpAuthenticationAction[] = []; + for (const { onSelect, ...action } of actions ?? []) { + resolvedActions.push(action); + } + + const replyPayload: InternalEventPayload = { + type: 'get_http_authentication_config_response', + args: resolvedArgs, + actions: resolvedActions, + pluginRefId: this.#workerData.pluginRefId, + }; + + this.#sendPayload(windowContext, replyPayload, replyId); + return; + } + + if (payload.type === 'call_http_authentication_request' && this.#mod?.authentication) { + const auth = this.#mod.authentication; + if (typeof auth?.onApply === 'function') { + applyFormInputDefaults(auth.args, payload.values); + const result = await auth.onApply(ctx, payload); + this.#sendPayload( + windowContext, + { + type: 'call_http_authentication_response', + setHeaders: result.setHeaders, + }, + replyId, + ); + return; + } + } + + if ( + payload.type === 'call_http_authentication_action_request' && + this.#mod.authentication != null + ) { + const action = this.#mod.authentication.actions?.[payload.index]; + if (typeof action?.onSelect === 'function') { + await action.onSelect(ctx, payload.args); + this.#sendEmpty(windowContext, replyId); + return; + } + } + + if ( + payload.type === 'call_http_request_action_request' && + Array.isArray(this.#mod.httpRequestActions) + ) { + const action = this.#mod.httpRequestActions[payload.index]; + if (typeof action?.onSelect === 'function') { + await action.onSelect(ctx, payload.args); + this.#sendEmpty(windowContext, replyId); + return; + } + } + + if ( + payload.type === 'call_template_function_request' && + Array.isArray(this.#mod?.templateFunctions) + ) { + const action = this.#mod.templateFunctions.find((a) => a.name === payload.name); + if (typeof action?.onRender === 'function') { + applyFormInputDefaults(action.args, payload.args.values); + const result = await action.onRender(ctx, payload.args); + this.#sendPayload( + windowContext, + { + type: 'call_template_function_response', + value: result ?? null, + }, + replyId, + ); + return; + } + } + + if (payload.type === 'reload_request') { + this.#importModule(); + } + } catch (err) { + console.log('Plugin call threw exception', payload.type, err); + this.#sendPayload( + windowContext, + { + type: 'error_response', + error: `${err}`, + }, + replyId, + ); + return; + } + + // No matches, so send back an empty response so the caller doesn't block forever + this.#sendEmpty(windowContext, replyId); + } + + #pathMod() { + return path.posix.join(this.#workerData.bootRequest.dir, 'build', 'index.js'); + } + + #pathPkg() { + return path.join(this.#workerData.bootRequest.dir, 'package.json'); + } + + #unimportModule() { + const id = require.resolve(this.#pathMod()); + delete require.cache[id]; + } + + #importModule() { + const id = require.resolve(this.#pathMod()); + delete require.cache[id]; + this.#mod = require(id).plugin; + } + + #buildEventToSend( + windowContext: WindowContext, + payload: InternalEventPayload, + replyId: string | null = null, + ): InternalEvent { + return { + pluginRefId: this.#workerData.pluginRefId, + pluginName: path.basename(this.#workerData.bootRequest.dir), + id: genId(), + replyId, + payload, + windowContext, + }; + } + + #sendPayload( + windowContext: WindowContext, + payload: InternalEventPayload, + replyId: string | null, + ): string { + const event = this.#buildEventToSend(windowContext, payload, replyId); + this.#sendEvent(event); + return event.id; + } + + #sendEvent(event: InternalEvent) { + if (event.payload.type !== 'empty_response') { + console.log('Sending event to app', event.id, event.payload.type); + } + this.#pluginToAppEvents.emit(event); + } + + #sendEmpty(windowContext: WindowContext, replyId: string | null = null): string { + return this.#sendPayload(windowContext, { type: 'empty_response' }, replyId); + } + + #sendAndWaitForReply>( + windowContext: WindowContext, + payload: InternalEventPayload, + ): Promise { + // 1. Build event to send + const eventToSend = this.#buildEventToSend(windowContext, payload, null); + + // 2. Spawn listener in background + const promise = new Promise((resolve) => { + const cb = (event: InternalEvent) => { + if (event.replyId === eventToSend.id) { + this.#appToPluginEvents.listen(cb); // Unlisten, now that we're done + const { type: _, ...payload } = event.payload; + resolve(payload as T); + } + }; + this.#appToPluginEvents.listen(cb); + }); + + // 3. Send the event after we start listening (to prevent race) + console.log("SENDING EVENT FOR REPLY", eventToSend); + this.#sendEvent(eventToSend); + + // 4. Return the listener promise + return promise as unknown as Promise; + } + + #sendAndListenForEvents( + windowContext: WindowContext, + payload: InternalEventPayload, + onEvent: (event: InternalEventPayload) => void, + ): void { + // 1. Build event to send + const eventToSend = this.#buildEventToSend(windowContext, payload, null); + + // 2. Listen for replies in the background + this.#appToPluginEvents.listen((event: InternalEvent) => { + if (event.replyId === eventToSend.id) { + onEvent(event.payload); + } + }); + + // 3. Send the event after we start listening (to prevent race) + this.#sendEvent(eventToSend); + } + + #newCtx(event: InternalEvent): Context { + return { + clipboard: { + copyText: async (text) => { + await this.#sendAndWaitForReply(event.windowContext, { + type: 'copy_text_request', + text, + }); + }, + }, + toast: { + show: async (args) => { + await this.#sendAndWaitForReply(event.windowContext, { + type: 'show_toast_request', + ...args, + }); + }, + }, + window: { + openUrl: async ({ onNavigate, ...args }) => { + args.label = args.label || `${Math.random()}`; + const payload: InternalEventPayload = { type: 'open_window_request', ...args }; + const onEvent = (event: InternalEventPayload) => { + if (event.type === 'window_navigate_event') { + onNavigate?.(event); + } + }; + this.#sendAndListenForEvents(event.windowContext, payload, onEvent); + return { + close: () => { + const closePayload: InternalEventPayload = { + type: 'close_window_request', + label: args.label, + }; + this.#sendPayload(event.windowContext, closePayload, null); + }, + }; + }, + }, + prompt: { + text: async (args) => { + const reply: PromptTextResponse = await this.#sendAndWaitForReply(event.windowContext, { + type: 'prompt_text_request', + ...args, + }); + return reply.value; + }, + }, + httpResponse: { + find: async (args) => { + const payload = { + type: 'find_http_responses_request', + ...args, + } as const; + const { httpResponses } = await this.#sendAndWaitForReply( + event.windowContext, + payload, + ); + return httpResponses; + }, + }, + httpRequest: { + getById: async (args) => { + const payload = { + type: 'get_http_request_by_id_request', + ...args, + } as const; + const { httpRequest } = await this.#sendAndWaitForReply( + event.windowContext, + payload, + ); + return httpRequest; + }, + send: async (args) => { + const payload = { + type: 'send_http_request_request', + ...args, + } as const; + const { httpResponse } = await this.#sendAndWaitForReply( + event.windowContext, + payload, + ); + return httpResponse; + }, + render: async (args) => { + const payload = { + type: 'render_http_request_request', + ...args, + } as const; + const { httpRequest } = await this.#sendAndWaitForReply( + event.windowContext, + payload, + ); + return httpRequest; + }, + }, + templates: { + /** + * Invoke Yaak's template engine to render a value. If the value is a nested type + * (eg. object), it will be recursively rendered. + */ + render: async (args) => { + const payload = { type: 'template_render_request', ...args } as const; + const result = await this.#sendAndWaitForReply( + event.windowContext, + payload, + ); + return result.data; + }, + }, + store: { + get: async (key: string) => { + const payload = { type: 'get_key_value_request', key } as const; + const result = await this.#sendAndWaitForReply( + event.windowContext, + payload, + ); + return result.value ? (JSON.parse(result.value) as T) : undefined; + }, + set: async (key: string, value: T) => { + const valueStr = JSON.stringify(value); + const payload: InternalEventPayload = { + type: 'set_key_value_request', + key, + value: valueStr, + }; + await this.#sendAndWaitForReply(event.windowContext, payload); + }, + delete: async (key: string) => { + const payload = { type: 'delete_key_value_request', key } as const; + const result = await this.#sendAndWaitForReply( + event.windowContext, + payload, + ); + return result.deleted; + }, + }, + }; + } +} + +function genId(len = 5): string { + const alphabet = '01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + let id = ''; + for (let i = 0; i < len; i++) { + id += alphabet[Math.floor(Math.random() * alphabet.length)]; + } + return id; +} + +/** Recursively apply form input defaults to a set of values */ +function applyFormInputDefaults( + inputs: FormInput[], + values: { [p: string]: JsonPrimitive | undefined }, +) { + for (const input of inputs) { + if ('inputs' in input) { + applyFormInputDefaults(input.inputs ?? [], values); + } else if ('defaultValue' in input && values[input.name] === undefined) { + values[input.name] = input.defaultValue; + } + } +} + +const watchedFiles: Record = {}; + +/** + * Watch a file and trigger callback on change. + * + * We also track the stat for each file because fs.watch() will + * trigger a "change" event when the access date changes + */ +function watchFile(filepath: string, cb: (filepath: string) => void) { + watch(filepath, () => { + const stat = statSync(filepath); + if (stat.mtimeMs !== watchedFiles[filepath]?.mtimeMs) { + cb(filepath); + } + watchedFiles[filepath] = stat; + }); +} + +// function prefixStdout(s: string) { +// if (!s.includes('%s')) { +// throw new Error('Console prefix must contain a "%s" replacer'); +// } +// interceptStdout((text: string) => { +// const lines = text.split(/\n/); +// let newText = ''; +// for (let i = 0; i < lines.length; i++) { +// if (lines[i] == '') continue; +// newText += util.format(s, lines[i]) + '\n'; +// } +// return newText.trimEnd(); +// }); +// } diff --git a/packages/plugin-runtime/src/index.ts b/packages/plugin-runtime/src/index.ts index 1611c0299..afdd0e22f 100644 --- a/packages/plugin-runtime/src/index.ts +++ b/packages/plugin-runtime/src/index.ts @@ -8,7 +8,7 @@ if (!port) { throw new Error('Plugin runtime missing PORT') } -const events = new EventChannel(); +const pluginToAppEvents = new EventChannel(); const plugins: Record = {}; const ws = new WebSocket(`ws://localhost:${port}`); @@ -25,7 +25,7 @@ ws.on('error', (err: any) => console.error('Plugin runtime websocket error', err ws.on('close', (code: number) => console.log('Plugin runtime websocket closed', code)); // Listen for incoming events from plugins -events.listen((e) => { +pluginToAppEvents.listen((e) => { const eventStr = JSON.stringify(e); ws.send(eventStr); }); @@ -34,7 +34,7 @@ async function handleIncoming(msg: string) { const pluginEvent: InternalEvent = JSON.parse(msg); // Handle special event to bootstrap plugin if (pluginEvent.payload.type === 'boot_request') { - const plugin = new PluginHandle(pluginEvent.pluginRefId, pluginEvent.payload, events); + const plugin = new PluginHandle(pluginEvent.pluginRefId, pluginEvent.payload, pluginToAppEvents); plugins[pluginEvent.pluginRefId] = plugin; } @@ -46,7 +46,7 @@ async function handleIncoming(msg: string) { } if (pluginEvent.payload.type === 'terminate_request') { - await plugin.terminate(); + plugin.terminate(); console.log('Terminated plugin worker', pluginEvent.pluginRefId); delete plugins[pluginEvent.pluginRefId]; } diff --git a/packages/plugin-runtime/src/index.worker.ts b/packages/plugin-runtime/src/index.worker.ts deleted file mode 100644 index aa888ffe3..000000000 --- a/packages/plugin-runtime/src/index.worker.ts +++ /dev/null @@ -1,568 +0,0 @@ -// OAuth 2.0 spec -> https://datatracker.ietf.org/doc/html/rfc6749 - -import type { - BootRequest, - Context, - DeleteKeyValueResponse, - FindHttpResponsesResponse, - FormInput, - GetHttpRequestByIdResponse, - GetKeyValueResponse, - HttpAuthenticationAction, - HttpRequestAction, - InternalEvent, - InternalEventPayload, - JsonPrimitive, - PluginDefinition, - PromptTextResponse, - RenderHttpRequestResponse, - SendHttpRequestResponse, - TemplateFunction, - TemplateRenderResponse, - WindowContext, -} from '@yaakapp/api'; -import * as console from 'node:console'; -import type { Stats } from 'node:fs'; -import { readFileSync, statSync, watch } from 'node:fs'; -import path from 'node:path'; -import * as util from 'node:util'; -import { parentPort as nullableParentPort, workerData } from 'node:worker_threads'; -import { interceptStdout } from './interceptStdout'; -import { migrateTemplateFunctionSelectOptions } from './migrations'; - -if (nullableParentPort == null) { - throw new Error('Worker does not have access to parentPort'); -} - -const parentPort = nullableParentPort; - -export interface PluginWorkerData { - bootRequest: BootRequest; - pluginRefId: string; -} - -function initialize(workerData: PluginWorkerData) { - const { - bootRequest: { dir: pluginDir, watch: enableWatch }, - pluginRefId, - }: PluginWorkerData = workerData; - - const pathPkg = path.join(pluginDir, 'package.json'); - const pathMod = path.posix.join(pluginDir, 'build', 'index.js'); - - const pkg = JSON.parse(readFileSync(pathPkg, 'utf8')); - - prefixStdout(`[plugin][${pkg.name}] %s`); - - function buildEventToSend( - windowContext: WindowContext, - payload: InternalEventPayload, - replyId: string | null = null, - ): InternalEvent { - return { - pluginRefId, - pluginName: path.basename(pluginDir), - id: genId(), - replyId, - payload, - windowContext, - }; - } - - function sendEmpty(windowContext: WindowContext, replyId: string | null = null): string { - return sendPayload(windowContext, { type: 'empty_response' }, replyId); - } - - function sendPayload( - windowContext: WindowContext, - payload: InternalEventPayload, - replyId: string | null, - ): string { - const event = buildEventToSend(windowContext, payload, replyId); - sendEvent(event); - return event.id; - } - - function sendEvent(event: InternalEvent) { - if (event.payload.type !== 'empty_response') { - console.log('Sending event to app', event.id, event.payload.type); - } - parentPort.postMessage(event); - } - - function sendAndWaitForReply>( - windowContext: WindowContext, - payload: InternalEventPayload, - ): Promise { - // 1. Build event to send - const eventToSend = buildEventToSend(windowContext, payload, null); - - // 2. Spawn listener in background - const promise = new Promise((resolve) => { - const cb = (event: InternalEvent) => { - if (event.replyId === eventToSend.id) { - parentPort.off('message', cb); // Unlisten, now that we're done - const { type: _, ...payload } = event.payload; - resolve(payload as T); - } - }; - parentPort.on('message', cb); - }); - - // 3. Send the event after we start listening (to prevent race) - sendEvent(eventToSend); - - // 4. Return the listener promise - return promise as unknown as Promise; - } - - function sendAndListenForEvents( - windowContext: WindowContext, - payload: InternalEventPayload, - onEvent: (event: InternalEventPayload) => void, - ): void { - // 1. Build event to send - const eventToSend = buildEventToSend(windowContext, payload, null); - - // 2. Listen for replies in the background - parentPort.on('message', (event: InternalEvent) => { - if (event.replyId === eventToSend.id) { - onEvent(event.payload); - } - }); - - // 3. Send the event after we start listening (to prevent race) - sendEvent(eventToSend); - } - - // Reload plugin if the JS or package.json changes - const windowContextNone: WindowContext = { type: 'none' }; - const fileChangeCallback = async () => { - importModule(); - return sendPayload(windowContextNone, { type: 'reload_response' }, null); - }; - - if (enableWatch) { - watchFile(pathMod, fileChangeCallback); - watchFile(pathPkg, fileChangeCallback); - } - - const newCtx = (event: InternalEvent): Context => ({ - clipboard: { - async copyText(text) { - await sendAndWaitForReply(event.windowContext, { - type: 'copy_text_request', - text, - }); - }, - }, - toast: { - async show(args) { - await sendAndWaitForReply(event.windowContext, { - type: 'show_toast_request', - ...args, - }); - }, - }, - window: { - async openUrl({ onNavigate, ...args }) { - args.label = args.label || `${Math.random()}`; - const payload: InternalEventPayload = { type: 'open_window_request', ...args }; - const onEvent = (event: InternalEventPayload) => { - if (event.type === 'window_navigate_event') { - onNavigate?.(event); - } - }; - sendAndListenForEvents(event.windowContext, payload, onEvent); - return { - close: () => { - const closePayload: InternalEventPayload = { - type: 'close_window_request', - label: args.label, - }; - sendPayload(event.windowContext, closePayload, null); - }, - }; - }, - }, - prompt: { - async text(args) { - const reply: PromptTextResponse = await sendAndWaitForReply(event.windowContext, { - type: 'prompt_text_request', - ...args, - }); - return reply.value; - }, - }, - httpResponse: { - async find(args) { - const payload = { - type: 'find_http_responses_request', - ...args, - } as const; - const { httpResponses } = await sendAndWaitForReply( - event.windowContext, - payload, - ); - return httpResponses; - }, - }, - httpRequest: { - async getById(args) { - const payload = { - type: 'get_http_request_by_id_request', - ...args, - } as const; - const { httpRequest } = await sendAndWaitForReply( - event.windowContext, - payload, - ); - return httpRequest; - }, - async send(args) { - const payload = { - type: 'send_http_request_request', - ...args, - } as const; - const { httpResponse } = await sendAndWaitForReply( - event.windowContext, - payload, - ); - return httpResponse; - }, - async render(args) { - const payload = { - type: 'render_http_request_request', - ...args, - } as const; - const { httpRequest } = await sendAndWaitForReply( - event.windowContext, - payload, - ); - return httpRequest; - }, - }, - templates: { - /** - * Invoke Yaak's template engine to render a value. If the value is a nested type - * (eg. object), it will be recursively rendered. - */ - async render(args) { - const payload = { type: 'template_render_request', ...args } as const; - const result = await sendAndWaitForReply( - event.windowContext, - payload, - ); - return result.data; - }, - }, - store: { - async get(key: string) { - const payload = { type: 'get_key_value_request', key } as const; - const result = await sendAndWaitForReply(event.windowContext, payload); - return result.value ? (JSON.parse(result.value) as T) : undefined; - }, - async set(key: string, value: T) { - const valueStr = JSON.stringify(value); - const payload: InternalEventPayload = { - type: 'set_key_value_request', - key, - value: valueStr, - }; - await sendAndWaitForReply(event.windowContext, payload); - }, - async delete(key: string) { - const payload = { type: 'delete_key_value_request', key } as const; - const result = await sendAndWaitForReply( - event.windowContext, - payload, - ); - return result.deleted; - }, - }, - }); - - let plug: PluginDefinition | null = null; - - function importModule() { - const id = require.resolve(pathMod); - delete require.cache[id]; - plug = require(id).plugin; - } - - importModule(); - - // Message comes into the plugin to be processed - parentPort.on('message', async (event: InternalEvent) => { - const ctx = newCtx(event); - const { windowContext, payload, id: replyId } = event; - try { - if (payload.type === 'boot_request') { - // console.log('Plugin initialized', pkg.name, { capabilities, enableWatch }); - const payload: InternalEventPayload = { - type: 'boot_response', - name: pkg.name, - version: pkg.version, - }; - sendPayload(windowContext, payload, replyId); - return; - } - - if (payload.type === 'terminate_request') { - const payload: InternalEventPayload = { - type: 'terminate_response', - }; - sendPayload(windowContext, payload, replyId); - return; - } - - if (payload.type === 'import_request' && typeof plug?.importer?.onImport === 'function') { - const reply = await plug.importer.onImport(ctx, { - text: payload.content, - }); - if (reply != null) { - const replyPayload: InternalEventPayload = { - type: 'import_response', - // deno-lint-ignore no-explicit-any - resources: reply.resources as any, - }; - sendPayload(windowContext, replyPayload, replyId); - return; - } else { - // Continue, to send back an empty reply - } - } - - if (payload.type === 'filter_request' && typeof plug?.filter?.onFilter === 'function') { - const reply = await plug.filter.onFilter(ctx, { - filter: payload.filter, - payload: payload.content, - mimeType: payload.type, - }); - const replyPayload: InternalEventPayload = { - type: 'filter_response', - content: reply.filtered, - }; - sendPayload(windowContext, replyPayload, replyId); - return; - } - - if ( - payload.type === 'get_http_request_actions_request' && - Array.isArray(plug?.httpRequestActions) - ) { - const reply: HttpRequestAction[] = plug.httpRequestActions.map((a) => ({ - ...a, - // Add everything except onSelect - onSelect: undefined, - })); - const replyPayload: InternalEventPayload = { - type: 'get_http_request_actions_response', - pluginRefId, - actions: reply, - }; - sendPayload(windowContext, replyPayload, replyId); - return; - } - - if ( - payload.type === 'get_template_functions_request' && - Array.isArray(plug?.templateFunctions) - ) { - const reply: TemplateFunction[] = plug.templateFunctions.map((templateFunction) => { - return { - ...migrateTemplateFunctionSelectOptions(templateFunction), - // Add everything except render - onRender: undefined, - }; - }); - const replyPayload: InternalEventPayload = { - type: 'get_template_functions_response', - pluginRefId, - functions: reply, - }; - sendPayload(windowContext, replyPayload, replyId); - return; - } - - if (payload.type === 'get_http_authentication_summary_request' && plug?.authentication) { - const { name, shortLabel, label } = plug.authentication; - const replyPayload: InternalEventPayload = { - type: 'get_http_authentication_summary_response', - name, - label, - shortLabel, - }; - - sendPayload(windowContext, replyPayload, replyId); - return; - } - - if (payload.type === 'get_http_authentication_config_request' && plug?.authentication) { - const { args, actions } = plug.authentication; - const resolvedArgs: FormInput[] = []; - for (let i = 0; i < args.length; i++) { - let v = args[i]; - if ('dynamic' in v) { - const dynamicAttrs = await v.dynamic(ctx, payload); - const { dynamic, ...other } = v; - resolvedArgs.push({ ...other, ...dynamicAttrs } as FormInput); - } else { - resolvedArgs.push(v); - } - } - const resolvedActions: HttpAuthenticationAction[] = []; - for (const { onSelect, ...action } of actions ?? []) { - resolvedActions.push(action); - } - - const replyPayload: InternalEventPayload = { - type: 'get_http_authentication_config_response', - args: resolvedArgs, - actions: resolvedActions, - pluginRefId, - }; - - sendPayload(windowContext, replyPayload, replyId); - return; - } - - if (payload.type === 'call_http_authentication_request' && plug?.authentication) { - const auth = plug.authentication; - if (typeof auth?.onApply === 'function') { - applyFormInputDefaults(auth.args, payload.values); - const result = await auth.onApply(ctx, payload); - sendPayload( - windowContext, - { - type: 'call_http_authentication_response', - setHeaders: result.setHeaders, - }, - replyId, - ); - return; - } - } - - if ( - payload.type === 'call_http_authentication_action_request' && - plug?.authentication != null - ) { - const action = plug.authentication.actions?.[payload.index]; - if (typeof action?.onSelect === 'function') { - await action.onSelect(ctx, payload.args); - sendEmpty(windowContext, replyId); - return; - } - } - - if ( - payload.type === 'call_http_request_action_request' && - Array.isArray(plug?.httpRequestActions) - ) { - const action = plug.httpRequestActions[payload.index]; - if (typeof action?.onSelect === 'function') { - await action.onSelect(ctx, payload.args); - sendEmpty(windowContext, replyId); - return; - } - } - - if ( - payload.type === 'call_template_function_request' && - Array.isArray(plug?.templateFunctions) - ) { - const action = plug.templateFunctions.find((a) => a.name === payload.name); - if (typeof action?.onRender === 'function') { - applyFormInputDefaults(action.args, payload.args.values); - const result = await action.onRender(ctx, payload.args); - sendPayload( - windowContext, - { - type: 'call_template_function_response', - value: result ?? null, - }, - replyId, - ); - return; - } - } - - if (payload.type === 'reload_request') { - importModule(); - } - } catch (err) { - console.log('Plugin call threw exception', payload.type, err); - sendPayload( - windowContext, - { - type: 'error_response', - error: `${err}`, - }, - replyId, - ); - return; - } - - // No matches, so send back an empty response so the caller doesn't block forever - sendEmpty(windowContext, replyId); - }); -} - -initialize(workerData); - -function genId(len = 5): string { - const alphabet = '01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - let id = ''; - for (let i = 0; i < len; i++) { - id += alphabet[Math.floor(Math.random() * alphabet.length)]; - } - return id; -} - -function prefixStdout(s: string) { - if (!s.includes('%s')) { - throw new Error('Console prefix must contain a "%s" replacer'); - } - interceptStdout((text: string) => { - const lines = text.split(/\n/); - let newText = ''; - for (let i = 0; i < lines.length; i++) { - if (lines[i] == '') continue; - newText += util.format(s, lines[i]) + '\n'; - } - return newText.trimEnd(); - }); -} - -const watchedFiles: Record = {}; - -/** - * Watch a file and trigger callback on change. - * - * We also track the stat for each file because fs.watch() will - * trigger a "change" event when the access date changes - */ -function watchFile(filepath: string, cb: (filepath: string) => void) { - watch(filepath, () => { - const stat = statSync(filepath); - if (stat.mtimeMs !== watchedFiles[filepath]?.mtimeMs) { - cb(filepath); - } - watchedFiles[filepath] = stat; - }); -} - -/** Recursively apply form input defaults to a set of values */ -function applyFormInputDefaults( - inputs: FormInput[], - values: { [p: string]: JsonPrimitive | undefined }, -) { - for (const input of inputs) { - if ('inputs' in input) { - applyFormInputDefaults(input.inputs ?? [], values); - } else if ('defaultValue' in input && values[input.name] === undefined) { - values[input.name] = input.defaultValue; - } - } -} diff --git a/src-tauri/src/plugin_events.rs b/src-tauri/src/plugin_events.rs index 2e4ecf2d3..bc35e753b 100644 --- a/src-tauri/src/plugin_events.rs +++ b/src-tauri/src/plugin_events.rs @@ -30,7 +30,7 @@ pub(crate) async fn handle_plugin_event( event: &InternalEvent, plugin_handle: &PluginHandle, ) { - // info!("Got event to app {}", event.id); + // debug!("Got event to app {event:?}"); let window_context = event.window_context.to_owned(); let response_event: Option = match event.clone().payload { InternalEventPayload::CopyTextRequest(req) => { diff --git a/src-tauri/vendored/plugins/auth-oauth2/build/index.js b/src-tauri/vendored/plugins/auth-oauth2/build/index.js index cc26357a4..f30555ea4 100644 --- a/src-tauri/vendored/plugins/auth-oauth2/build/index.js +++ b/src-tauri/vendored/plugins/auth-oauth2/build/index.js @@ -461,17 +461,24 @@ var plugin = { options: grantTypes }, // Always-present fields - { type: "text", name: "clientId", label: "Client ID" }, + { + type: "text", + name: "clientId", + label: "Client ID", + optional: true + }, { type: "text", name: "clientSecret", label: "Client Secret", + optional: true, password: true, dynamic: hiddenIfNot(["authorization_code", "password", "client_credentials"]) }, { type: "text", name: "authorizationUrl", + optional: true, label: "Authorization URL", dynamic: hiddenIfNot(["authorization_code", "implicit"]), placeholder: authorizationUrls[0], @@ -480,6 +487,7 @@ var plugin = { { type: "text", name: "accessTokenUrl", + optional: true, label: "Access Token URL", placeholder: accessTokenUrls[0], dynamic: hiddenIfNot(["authorization_code", "password", "client_credentials"]), @@ -590,55 +598,55 @@ var plugin = { } ], async onApply(ctx, { values, contextId }) { - const headerPrefix = optionalString(values, "headerPrefix") ?? ""; - const grantType = requiredString(values, "grantType"); + const headerPrefix = stringArg(values, "headerPrefix"); + const grantType = stringArg(values, "grantType"); const credentialsInBody = values.credentials === "body"; let token; if (grantType === "authorization_code") { - const authorizationUrl = requiredString(values, "authorizationUrl"); - const accessTokenUrl = requiredString(values, "accessTokenUrl"); + const authorizationUrl = stringArg(values, "authorizationUrl"); + const accessTokenUrl = stringArg(values, "accessTokenUrl"); token = await getAuthorizationCode(ctx, contextId, { accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`, authorizationUrl: authorizationUrl.match(/^https?:\/\//) ? authorizationUrl : `https://${authorizationUrl}`, - clientId: requiredString(values, "clientId"), - clientSecret: requiredString(values, "clientSecret"), - redirectUri: optionalString(values, "redirectUri"), - scope: optionalString(values, "scope"), - state: optionalString(values, "state"), + clientId: stringArg(values, "clientId"), + clientSecret: stringArg(values, "clientSecret"), + redirectUri: stringArgOrNull(values, "redirectUri"), + scope: stringArgOrNull(values, "scope"), + state: stringArgOrNull(values, "state"), credentialsInBody, pkce: values.usePkce ? { - challengeMethod: requiredString(values, "pkceChallengeMethod"), - codeVerifier: optionalString(values, "pkceCodeVerifier") + challengeMethod: stringArg(values, "pkceChallengeMethod"), + codeVerifier: stringArgOrNull(values, "pkceCodeVerifier") } : null }); } else if (grantType === "implicit") { - const authorizationUrl = requiredString(values, "authorizationUrl"); + const authorizationUrl = stringArg(values, "authorizationUrl"); token = await getImplicit(ctx, contextId, { authorizationUrl: authorizationUrl.match(/^https?:\/\//) ? authorizationUrl : `https://${authorizationUrl}`, - clientId: requiredString(values, "clientId"), - redirectUri: optionalString(values, "redirectUri"), - responseType: requiredString(values, "responseType"), - scope: optionalString(values, "scope"), - state: optionalString(values, "state") + clientId: stringArg(values, "clientId"), + redirectUri: stringArgOrNull(values, "redirectUri"), + responseType: stringArg(values, "responseType"), + scope: stringArgOrNull(values, "scope"), + state: stringArgOrNull(values, "state") }); } else if (grantType === "client_credentials") { - const accessTokenUrl = requiredString(values, "accessTokenUrl"); + const accessTokenUrl = stringArg(values, "accessTokenUrl"); token = await getClientCredentials(ctx, contextId, { accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`, - clientId: requiredString(values, "clientId"), - clientSecret: requiredString(values, "clientSecret"), - scope: optionalString(values, "scope"), + clientId: stringArg(values, "clientId"), + clientSecret: stringArg(values, "clientSecret"), + scope: stringArgOrNull(values, "scope"), credentialsInBody }); } else if (grantType === "password") { - const accessTokenUrl = requiredString(values, "accessTokenUrl"); + const accessTokenUrl = stringArg(values, "accessTokenUrl"); token = await getPassword(ctx, contextId, { accessTokenUrl: accessTokenUrl.match(/^https?:\/\//) ? accessTokenUrl : `https://${accessTokenUrl}`, - clientId: requiredString(values, "clientId"), - clientSecret: requiredString(values, "clientSecret"), - username: requiredString(values, "username"), - password: requiredString(values, "password"), - scope: optionalString(values, "scope"), + clientId: stringArg(values, "clientId"), + clientSecret: stringArg(values, "clientSecret"), + username: stringArg(values, "username"), + password: stringArg(values, "password"), + scope: stringArgOrNull(values, "scope"), credentialsInBody }); } else { @@ -654,14 +662,14 @@ var plugin = { } } }; -function optionalString(values, name) { +function stringArgOrNull(values, name) { const arg = values[name]; if (arg == null || arg == "") return null; return `${arg}`; } -function requiredString(values, name) { - const arg = optionalString(values, name); - if (!arg) throw new Error(`Missing required argument ${name}`); +function stringArg(values, name) { + const arg = stringArgOrNull(values, name); + if (!arg) return ""; return arg; } // Annotate the CommonJS export names for ESM import in node: diff --git a/src-tauri/vendored/plugins/exporter-curl/build/index.js b/src-tauri/vendored/plugins/exporter-curl/build/index.js index 971450fb0..2965d8b7c 100644 --- a/src-tauri/vendored/plugins/exporter-curl/build/index.js +++ b/src-tauri/vendored/plugins/exporter-curl/build/index.js @@ -30,9 +30,13 @@ var plugin = { label: "Copy as Curl", icon: "copy", async onSelect(ctx, args) { + console.log("---------------------------", 0); const rendered_request = await ctx.httpRequest.render({ httpRequest: args.httpRequest, purpose: "preview" }); + console.log("---------------------------", 1); const data = await convertToCurl(rendered_request); + console.log("---------------------------", 2); await ctx.clipboard.copyText(data); + console.log("---------------------------", 3); await ctx.toast.show({ message: "Curl copied to clipboard", icon: "copy", color: "success" }); } }] diff --git a/src-tauri/yaak-plugins/src/manager.rs b/src-tauri/yaak-plugins/src/manager.rs index e86439d2d..371c40887 100644 --- a/src-tauri/yaak-plugins/src/manager.rs +++ b/src-tauri/yaak-plugins/src/manager.rs @@ -206,7 +206,7 @@ impl PluginManager { // Boot the plugin let event = timeout( - Duration::from_secs(1), + Duration::from_secs(2), self.send_to_plugin_and_wait( window_context, &plugin_handle, diff --git a/src-tauri/yaak-plugins/src/plugin_handle.rs b/src-tauri/yaak-plugins/src/plugin_handle.rs index 6525fc983..95416b980 100644 --- a/src-tauri/yaak-plugins/src/plugin_handle.rs +++ b/src-tauri/yaak-plugins/src/plugin_handle.rs @@ -74,6 +74,7 @@ impl PluginHandle { } pub async fn set_boot_response(&self, resp: &BootResponse) { + info!("BOOTED PLUGIN {:?}", resp); let mut boot_resp = self.boot_resp.lock().await; *boot_resp = resp.clone(); } diff --git a/src-tauri/yaak-sync/index.ts b/src-tauri/yaak-sync/index.ts index 233812bfa..3d5bd4a69 100644 --- a/src-tauri/yaak-sync/index.ts +++ b/src-tauri/yaak-sync/index.ts @@ -77,5 +77,7 @@ function removeWatchKey(key: string) { // On page load, unlisten to all zombie watchers const keys = getWatchKeys(); -console.log('Unsubscribing to zombie file watchers', keys); -keys.forEach(unlistenToWatcher); +if (keys.length > 0) { + console.log('Unsubscribing to zombie file watchers', keys); + keys.forEach(unlistenToWatcher); +} From 7f8b0479e11097817721cf47e9bc74865fe73484 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 24 Feb 2025 22:32:40 -0800 Subject: [PATCH 071/996] Plugin window data directory key --- packages/plugin-runtime-types/package.json | 2 +- .../src/bindings/gen_events.ts | 4 +- .../src/plugins/Context.ts | 5 +- packages/plugin-runtime/src/EventChannel.ts | 15 +++-- packages/plugin-runtime/src/PluginInstance.ts | 13 ++-- src-tauri/src/lib.rs | 4 +- src-tauri/src/plugin_events.rs | 59 +++++++++++++------ src-tauri/src/window.rs | 39 +++++++++++- .../plugins/auth-oauth2/build/index.js | 26 +++++++- .../plugins/exporter-curl/build/index.js | 4 -- src-tauri/yaak-plugins/bindings/gen_events.ts | 4 +- src-tauri/yaak-plugins/src/events.rs | 10 +++- src-web/components/core/Banner.tsx | 24 ++++---- 13 files changed, 153 insertions(+), 56 deletions(-) diff --git a/packages/plugin-runtime-types/package.json b/packages/plugin-runtime-types/package.json index ae59ee9a9..e376f5e93 100644 --- a/packages/plugin-runtime-types/package.json +++ b/packages/plugin-runtime-types/package.json @@ -1,6 +1,6 @@ { "name": "@yaakapp/api", - "version": "0.4.1", + "version": "0.5.0", "main": "lib/index.js", "typings": "./lib/index.d.ts", "files": [ diff --git a/packages/plugin-runtime-types/src/bindings/gen_events.ts b/packages/plugin-runtime-types/src/bindings/gen_events.ts index b2b7e0a6e..155214e9e 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_events.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_events.ts @@ -346,7 +346,7 @@ export type ImportResponse = { resources: ImportResources, }; export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: WindowContext, payload: InternalEventPayload, }; -export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; +export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; export type JsonPrimitive = string | number | boolean | null; @@ -354,7 +354,7 @@ export type OpenWindowRequest = { url: string, /** * Label for the window. If not provided, a random one will be generated. */ -label: string, title?: string, size?: WindowSize, }; +label: string, title?: string, size?: WindowSize, dataDirKey?: string, }; export type PromptTextRequest = { id: string, title: string, label: string, description?: string, defaultValue?: string, placeholder?: string, /** diff --git a/packages/plugin-runtime-types/src/plugins/Context.ts b/packages/plugin-runtime-types/src/plugins/Context.ts index 39c288eef..15715c650 100644 --- a/packages/plugin-runtime-types/src/plugins/Context.ts +++ b/packages/plugin-runtime-types/src/plugins/Context.ts @@ -32,7 +32,10 @@ export interface Context { }; window: { openUrl( - args: OpenWindowRequest & { onNavigate?: (args: { url: string }) => void }, + args: OpenWindowRequest & { + onNavigate?: (args: { url: string }) => void; + onClose: () => void; + }, ): Promise<{ close: () => void }>; }; httpRequest: { diff --git a/packages/plugin-runtime/src/EventChannel.ts b/packages/plugin-runtime/src/EventChannel.ts index 4275b6a05..b80802e86 100644 --- a/packages/plugin-runtime/src/EventChannel.ts +++ b/packages/plugin-runtime/src/EventChannel.ts @@ -1,14 +1,19 @@ -import type { InternalEvent } from "@yaakapp/api"; -import EventEmitter from "node:events"; +import type { InternalEvent } from '@yaakapp/api'; export class EventChannel { - emitter: EventEmitter = new EventEmitter(); + #listeners = new Set<(event: InternalEvent) => void>(); emit(e: InternalEvent) { - this.emitter.emit("__plugin_event__", e); + for (const l of this.#listeners) { + l(e); + } } listen(cb: (e: InternalEvent) => void) { - this.emitter.on("__plugin_event__", cb); + this.#listeners.add(cb); + } + + unlisten(cb: (e: InternalEvent) => void) { + this.#listeners.delete(cb); } } diff --git a/packages/plugin-runtime/src/PluginInstance.ts b/packages/plugin-runtime/src/PluginInstance.ts index dc9fab322..997349a7a 100644 --- a/packages/plugin-runtime/src/PluginInstance.ts +++ b/packages/plugin-runtime/src/PluginInstance.ts @@ -342,9 +342,9 @@ export class PluginInstance { } #sendEvent(event: InternalEvent) { - if (event.payload.type !== 'empty_response') { - console.log('Sending event to app', event.id, event.payload.type); - } + // if (event.payload.type !== 'empty_response') { + // console.log('Sending event to app', this.#pkg.name, event.id, event.payload.type); + // } this.#pluginToAppEvents.emit(event); } @@ -363,7 +363,7 @@ export class PluginInstance { const promise = new Promise((resolve) => { const cb = (event: InternalEvent) => { if (event.replyId === eventToSend.id) { - this.#appToPluginEvents.listen(cb); // Unlisten, now that we're done + this.#appToPluginEvents.unlisten(cb); // Unlisten, now that we're done const { type: _, ...payload } = event.payload; resolve(payload as T); } @@ -372,7 +372,6 @@ export class PluginInstance { }); // 3. Send the event after we start listening (to prevent race) - console.log("SENDING EVENT FOR REPLY", eventToSend); this.#sendEvent(eventToSend); // 4. Return the listener promise @@ -417,12 +416,14 @@ export class PluginInstance { }, }, window: { - openUrl: async ({ onNavigate, ...args }) => { + openUrl: async ({ onNavigate, onClose, ...args }) => { args.label = args.label || `${Math.random()}`; const payload: InternalEventPayload = { type: 'open_window_request', ...args }; const onEvent = (event: InternalEventPayload) => { if (event.type === 'window_navigate_event') { onNavigate?.(event); + } else if (event.type === 'window_close_event') { + onClose?.(); } }; this.#sendAndListenForEvents(event.windowContext, payload, onEvent); diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index f0998b438..77265f3eb 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1658,8 +1658,8 @@ async fn cmd_new_child_window( url, inner_size: Some(inner_size), position: Some(position), - navigation_tx: None, hide_titlebar: true, + ..Default::default() }; let child_window = window::create_window(&app_handle, config); @@ -2014,8 +2014,8 @@ fn create_main_window(handle: &AppHandle, url: &str) -> WebviewWindow { 100.0 + random::() * 20.0, 100.0 + random::() * 20.0, )), - navigation_tx: None, hide_titlebar: true, + ..Default::default() }; window::create_window(handle, config) diff --git a/src-tauri/src/plugin_events.rs b/src-tauri/src/plugin_events.rs index bc35e753b..4c991f6ba 100644 --- a/src-tauri/src/plugin_events.rs +++ b/src-tauri/src/plugin_events.rs @@ -204,32 +204,55 @@ pub(crate) async fn handle_plugin_event( } InternalEventPayload::OpenWindowRequest(req) => { let label = req.label; - let (tx, mut rx) = tokio::sync::mpsc::channel(128); + let (navigation_tx, mut navigation_rx) = tokio::sync::mpsc::channel(128); + let (close_tx, mut close_rx) = tokio::sync::mpsc::channel(128); let win_config = CreateWindowConfig { url: &req.url, label: &label.clone(), title: &req.title.unwrap_or_default(), - navigation_tx: Some(tx), + navigation_tx: Some(navigation_tx), + close_tx: Some(close_tx), inner_size: req.size.map(|s| (s.width, s.height)), - position: None, - hide_titlebar: false, + data_dir_key: req.data_dir_key, + ..Default::default() }; create_window(app_handle, win_config); - let event_id = event.id.clone(); - let plugin_handle = plugin_handle.clone(); - tauri::async_runtime::spawn(async move { - while let Some(url) = rx.recv().await { - let label = label.clone(); - let url = url.to_string(); - let event_to_send = plugin_handle.build_event_to_send( - &WindowContext::Label { label }, - &InternalEventPayload::WindowNavigateEvent(WindowNavigateEvent { url }), - Some(event_id.clone()), - ); - plugin_handle.send(&event_to_send).await.unwrap(); - } - }); + { + let event_id = event.id.clone(); + let plugin_handle = plugin_handle.clone(); + let label = label.clone(); + tauri::async_runtime::spawn(async move { + while let Some(url) = navigation_rx.recv().await { + let url = url.to_string(); + let label = label.clone(); + let event_to_send = plugin_handle.build_event_to_send( + &WindowContext::Label { label }, + &InternalEventPayload::WindowNavigateEvent(WindowNavigateEvent { url }), + Some(event_id.clone()), + ); + plugin_handle.send(&event_to_send).await.unwrap(); + } + }); + } + + { + let event_id = event.id.clone(); + let plugin_handle = plugin_handle.clone(); + let label = label.clone(); + tauri::async_runtime::spawn(async move { + while let Some(_) = close_rx.recv().await { + let label = label.clone(); + let event_to_send = plugin_handle.build_event_to_send( + &WindowContext::Label { label }, + &InternalEventPayload::WindowCloseEvent, + Some(event_id.clone()), + ); + plugin_handle.send(&event_to_send).await.unwrap(); + } + }); + } + None } InternalEventPayload::CloseWindowRequest(req) => { diff --git a/src-tauri/src/window.rs b/src-tauri/src/window.rs index c2df780dd..b6f0a858b 100644 --- a/src-tauri/src/window.rs +++ b/src-tauri/src/window.rs @@ -3,7 +3,7 @@ use crate::{DEFAULT_WINDOW_HEIGHT, DEFAULT_WINDOW_WIDTH, MIN_WINDOW_HEIGHT, MIN_ use log::{info, warn}; use std::process::exit; use tauri::{ - AppHandle, Emitter, LogicalSize, Manager, Runtime, WebviewUrl, WebviewWindow, + AppHandle, Emitter, LogicalSize, Manager, Runtime, WebviewUrl, WebviewWindow, WindowEvent, }; use tauri_plugin_opener::OpenerExt; use tokio::sync::mpsc; @@ -16,6 +16,8 @@ pub(crate) struct CreateWindowConfig<'s> { pub inner_size: Option<(f64, f64)>, pub position: Option<(f64, f64)>, pub navigation_tx: Option>, + pub close_tx: Option>, + pub data_dir_key: Option, pub hide_titlebar: bool, } @@ -41,6 +43,22 @@ pub(crate) fn create_window( .disable_drag_drop_handler() // Required for frontend Dnd on windows .min_inner_size(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT); + if let Some(key) = config.data_dir_key { + #[cfg(not(target_os = "macos"))] + { + use std::fs; + let dir = handle.path().temp_dir().unwrap().join("yaak_sessions").join(key); + fs::create_dir_all(dir.clone()).unwrap(); + win_builder = win_builder.data_directory(dir); + } + + // macOS doesn't support data dir so must use this fn instead + #[cfg(target_os = "macos")] + { + win_builder = win_builder.data_store_identifier(to_fixed_hash(&key)); + } + } + if let Some((w, h)) = config.inner_size { win_builder = win_builder.inner_size(w, h); } else { @@ -85,6 +103,18 @@ pub(crate) fn create_window( let win = win_builder.build().unwrap(); + if let Some(tx) = config.close_tx { + win.on_window_event(move |event| match event { + WindowEvent::CloseRequested { .. } => { + let tx = tx.clone(); + tauri::async_runtime::block_on(async move { + tx.send(()).await.unwrap(); + }); + } + _ => {} + }); + } + let webview_window = win.clone(); win.on_menu_event(move |w, event| { if !w.is_focused().unwrap() { @@ -128,3 +158,10 @@ pub(crate) fn create_window( win } + +fn to_fixed_hash(s: &str) -> [u8; 16] { + let hash = md5::compute(s.as_bytes()); + let mut fixed = [0u8; 16]; + fixed.copy_from_slice(&hash[..16]); // Take the first 16 bytes of the hash + fixed +} diff --git a/src-tauri/vendored/plugins/auth-oauth2/build/index.js b/src-tauri/vendored/plugins/auth-oauth2/build/index.js index f30555ea4..051fbda18 100644 --- a/src-tauri/vendored/plugins/auth-oauth2/build/index.js +++ b/src-tauri/vendored/plugins/auth-oauth2/build/index.js @@ -102,9 +102,19 @@ async function getToken(ctx, contextId) { async function deleteToken(ctx, contextId) { return ctx.store.delete(tokenStoreKey(contextId)); } +async function resetDataDirKey(ctx, contextId) { + const key = (/* @__PURE__ */ new Date()).toISOString(); + return ctx.store.set(dataDirStoreKey(contextId), key); +} +async function getDataDirKey(ctx, contextId) { + return ctx.store.get(dataDirStoreKey(contextId)); +} function tokenStoreKey(context_id) { return ["token", context_id].join("::"); } +function dataDirStoreKey(context_id) { + return ["data_dir", context_id].join("::"); +} // src/getOrRefreshAccessToken.ts async function getOrRefreshAccessToken(ctx, contextId, { @@ -218,9 +228,16 @@ async function getAuthorizationCode(ctx, contextId, { return new Promise(async (resolve, reject) => { const authorizationUrlStr = authorizationUrl.toString(); console.log("Authorizing", authorizationUrlStr); + let foundCode = false; let { close } = await ctx.window.openUrl({ url: authorizationUrlStr, label: "oauth-authorization-url", + dataDirKey: await getDataDirKey(ctx, contextId), + async onClose() { + if (!foundCode) { + reject(new Error("Authorization window closed")); + } + }, async onNavigate({ url: urlStr }) { const url = new URL(urlStr); if (url.searchParams.has("error")) { @@ -230,6 +247,7 @@ async function getAuthorizationCode(ctx, contextId, { if (!code) { return; } + foundCode = true; close(); const response = await getAccessToken(ctx, { grantType: "authorization_code", @@ -428,7 +446,6 @@ var plugin = { actions: [ { label: "Copy Current Token", - icon: "copy", async onSelect(ctx, { contextId }) { const token = await getToken(ctx, contextId); if (token == null) { @@ -441,7 +458,6 @@ var plugin = { }, { label: "Delete Token", - icon: "trash", async onSelect(ctx, { contextId }) { if (await deleteToken(ctx, contextId)) { await ctx.toast.show({ message: "Token deleted", color: "success" }); @@ -449,6 +465,12 @@ var plugin = { await ctx.toast.show({ message: "No token to delete", color: "warning" }); } } + }, + { + label: "Clear Window Session", + async onSelect(ctx, { contextId }) { + await resetDataDirKey(ctx, contextId); + } } ], args: [ diff --git a/src-tauri/vendored/plugins/exporter-curl/build/index.js b/src-tauri/vendored/plugins/exporter-curl/build/index.js index 2965d8b7c..971450fb0 100644 --- a/src-tauri/vendored/plugins/exporter-curl/build/index.js +++ b/src-tauri/vendored/plugins/exporter-curl/build/index.js @@ -30,13 +30,9 @@ var plugin = { label: "Copy as Curl", icon: "copy", async onSelect(ctx, args) { - console.log("---------------------------", 0); const rendered_request = await ctx.httpRequest.render({ httpRequest: args.httpRequest, purpose: "preview" }); - console.log("---------------------------", 1); const data = await convertToCurl(rendered_request); - console.log("---------------------------", 2); await ctx.clipboard.copyText(data); - console.log("---------------------------", 3); await ctx.toast.show({ message: "Curl copied to clipboard", icon: "copy", color: "success" }); } }] diff --git a/src-tauri/yaak-plugins/bindings/gen_events.ts b/src-tauri/yaak-plugins/bindings/gen_events.ts index b2b7e0a6e..155214e9e 100644 --- a/src-tauri/yaak-plugins/bindings/gen_events.ts +++ b/src-tauri/yaak-plugins/bindings/gen_events.ts @@ -346,7 +346,7 @@ export type ImportResponse = { resources: ImportResources, }; export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: WindowContext, payload: InternalEventPayload, }; -export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; +export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; export type JsonPrimitive = string | number | boolean | null; @@ -354,7 +354,7 @@ export type OpenWindowRequest = { url: string, /** * Label for the window. If not provided, a random one will be generated. */ -label: string, title?: string, size?: WindowSize, }; +label: string, title?: string, size?: WindowSize, dataDirKey?: string, }; export type PromptTextRequest = { id: string, title: string, label: string, description?: string, defaultValue?: string, placeholder?: string, /** diff --git a/src-tauri/yaak-plugins/src/events.rs b/src-tauri/yaak-plugins/src/events.rs index 3676bbe10..a28b12a0d 100644 --- a/src-tauri/yaak-plugins/src/events.rs +++ b/src-tauri/yaak-plugins/src/events.rs @@ -3,7 +3,9 @@ use std::collections::HashMap; use tauri::{Runtime, WebviewWindow}; use ts_rs::TS; -use yaak_models::models::{Environment, Folder, GrpcRequest, HttpRequest, HttpResponse, WebsocketRequest, Workspace}; +use yaak_models::models::{ + Environment, Folder, GrpcRequest, HttpRequest, HttpResponse, WebsocketRequest, Workspace, +}; #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "camelCase")] @@ -108,6 +110,7 @@ pub enum InternalEventPayload { OpenWindowRequest(OpenWindowRequest), WindowNavigateEvent(WindowNavigateEvent), + WindowCloseEvent, CloseWindowRequest(CloseWindowRequest), TemplateRenderRequest(TemplateRenderRequest), @@ -262,10 +265,15 @@ pub struct OpenWindowRequest { pub url: String, /// Label for the window. If not provided, a random one will be generated. pub label: String, + #[ts(optional)] pub title: Option, + #[ts(optional)] pub size: Option, + + #[ts(optional)] + pub data_dir_key: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] diff --git a/src-web/components/core/Banner.tsx b/src-web/components/core/Banner.tsx index 7afa055ee..f4776ac3d 100644 --- a/src-web/components/core/Banner.tsx +++ b/src-web/components/core/Banner.tsx @@ -9,17 +9,19 @@ interface Props { export function Banner({ children, className, color }: Props) { return ( -
- {children} +
+
+ {children} +
); } From c0dbe46318c53ef114c238f8ed1464fd4e807e99 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 24 Feb 2025 22:34:10 -0800 Subject: [PATCH 072/996] Better data key for window --- package-lock.json | 8 ++++---- package.json | 2 +- .../auth-oauth2/src/grants/authorizationCode.ts | 12 +++++++++++- plugins/auth-oauth2/src/index.ts | 10 +++++++--- plugins/auth-oauth2/src/store.ts | 14 ++++++++++++++ 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9bf7fb642..b75323609 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.4.1" + "@yaakapp/api": "^0.5.0" }, "devDependencies": { "@types/node": "^22.7.4", @@ -930,9 +930,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.4.1.tgz", - "integrity": "sha512-qRpCuL2Wq9BJXbB6tHSQjaXGq0ZBQwnd87nWdeOPWMvmKCfFTPhxQh4x9/aFN1bTncNHcV3OdeXFTKMl0tB0Ng==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.5.0.tgz", + "integrity": "sha512-M0PPLGWQft+eQOOJ7ubwvRm3LTYXjAWQ8nniiqV3TkRcwa5++PteIH0OHV2L3Pei8cRQA8S25AD+RajyvFC8XQ==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/package.json b/package.json index 29d6f4665..ef57489af 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.4.1" + "@yaakapp/api": "^0.5.0" } } diff --git a/plugins/auth-oauth2/src/grants/authorizationCode.ts b/plugins/auth-oauth2/src/grants/authorizationCode.ts index 8d06dd7a7..247a3a725 100644 --- a/plugins/auth-oauth2/src/grants/authorizationCode.ts +++ b/plugins/auth-oauth2/src/grants/authorizationCode.ts @@ -2,7 +2,7 @@ import { Context } from '@yaakapp/api'; import { createHash, randomBytes } from 'node:crypto'; import { getAccessToken } from '../getAccessToken'; import { getOrRefreshAccessToken } from '../getOrRefreshAccessToken'; -import { AccessToken, storeToken } from '../store'; +import { AccessToken, getDataDirKey, storeToken } from '../store'; export const PKCE_SHA256 = 'S256'; export const PKCE_PLAIN = 'plain'; @@ -63,9 +63,18 @@ export async function getAuthorizationCode( return new Promise(async (resolve, reject) => { const authorizationUrlStr = authorizationUrl.toString(); console.log('Authorizing', authorizationUrlStr); + + let foundCode = false; + let { close } = await ctx.window.openUrl({ url: authorizationUrlStr, label: 'oauth-authorization-url', + dataDirKey: await getDataDirKey(ctx, contextId), + async onClose() { + if (!foundCode) { + reject(new Error('Authorization window closed')); + } + }, async onNavigate({ url: urlStr }) { const url = new URL(urlStr); if (url.searchParams.has('error')) { @@ -77,6 +86,7 @@ export async function getAuthorizationCode( } // Close the window here, because we don't need it anymore! + foundCode = true; close(); const response = await getAccessToken(ctx, { diff --git a/plugins/auth-oauth2/src/index.ts b/plugins/auth-oauth2/src/index.ts index 43ade852b..60ae2cf3e 100644 --- a/plugins/auth-oauth2/src/index.ts +++ b/plugins/auth-oauth2/src/index.ts @@ -9,7 +9,7 @@ import { DEFAULT_PKCE_METHOD, getAuthorizationCode, PKCE_PLAIN, PKCE_SHA256 } fr import { getClientCredentials } from './grants/clientCredentials'; import { getImplicit } from './grants/implicit'; import { getPassword } from './grants/password'; -import { AccessToken, deleteToken, getToken } from './store'; +import { AccessToken, deleteToken, getToken, resetDataDirKey } from './store'; type GrantType = 'authorization_code' | 'implicit' | 'password' | 'client_credentials'; @@ -71,7 +71,6 @@ export const plugin: PluginDefinition = { actions: [ { label: 'Copy Current Token', - icon: 'copy', async onSelect(ctx, { contextId }) { const token = await getToken(ctx, contextId); if (token == null) { @@ -84,7 +83,6 @@ export const plugin: PluginDefinition = { }, { label: 'Delete Token', - icon: 'trash', async onSelect(ctx, { contextId }) { if (await deleteToken(ctx, contextId)) { await ctx.toast.show({ message: 'Token deleted', color: 'success' }); @@ -93,6 +91,12 @@ export const plugin: PluginDefinition = { } }, }, + { + label: 'Clear Window Session', + async onSelect(ctx, { contextId }) { + await resetDataDirKey(ctx, contextId); + }, + }, ], args: [ { diff --git a/plugins/auth-oauth2/src/store.ts b/plugins/auth-oauth2/src/store.ts index bc1675ed9..89bf43e6d 100644 --- a/plugins/auth-oauth2/src/store.ts +++ b/plugins/auth-oauth2/src/store.ts @@ -22,10 +22,24 @@ export async function deleteToken(ctx: Context, contextId: string) { return ctx.store.delete(tokenStoreKey(contextId)); } +export async function resetDataDirKey(ctx: Context, contextId: string) { + const key = new Date().toISOString(); + return ctx.store.set(dataDirStoreKey(contextId), key); +} + +export async function getDataDirKey(ctx: Context, contextId: string) { + const key = (await ctx.store.get(dataDirStoreKey(contextId))) ?? 'default'; + return `${contextId}::${key}`; +} + function tokenStoreKey(context_id: string) { return ['token', context_id].join('::'); } +function dataDirStoreKey(context_id: string) { + return ['data_dir', context_id].join('::'); +} + export interface AccessToken { response: AccessTokenRawResponse, expiresAt: number | null; From 7e1da4395d01fd3a369300082f4791ab3a9862bb Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 24 Feb 2025 22:34:29 -0800 Subject: [PATCH 073/996] Build OAuth 2 plugin --- src-tauri/vendored/plugins/auth-oauth2/build/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src-tauri/vendored/plugins/auth-oauth2/build/index.js b/src-tauri/vendored/plugins/auth-oauth2/build/index.js index 051fbda18..18026a400 100644 --- a/src-tauri/vendored/plugins/auth-oauth2/build/index.js +++ b/src-tauri/vendored/plugins/auth-oauth2/build/index.js @@ -107,7 +107,8 @@ async function resetDataDirKey(ctx, contextId) { return ctx.store.set(dataDirStoreKey(contextId), key); } async function getDataDirKey(ctx, contextId) { - return ctx.store.get(dataDirStoreKey(contextId)); + const key = await ctx.store.get(dataDirStoreKey(contextId)) ?? "default"; + return `${contextId}::${key}`; } function tokenStoreKey(context_id) { return ["token", context_id].join("::"); From d297e92a5aaba5a9908ff942573191d2d0db985c Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 24 Feb 2025 22:44:58 -0800 Subject: [PATCH 074/996] Fix content type parsing exception --- src-web/lib/contentType.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src-web/lib/contentType.ts b/src-web/lib/contentType.ts index 608362e26..c58a0feee 100644 --- a/src-web/lib/contentType.ts +++ b/src-web/lib/contentType.ts @@ -75,7 +75,10 @@ export function isProbablyTextContentType(contentType: string | null): boolean { ].some((textType) => normalized === textType || normalized.endsWith(textType)); } -export function getMimeTypeFromContentType(contentType: string) { - const mimeType = new MimeType(contentType); - return mimeType; +export function getMimeTypeFromContentType(contentType: string): MimeType { + try { + return new MimeType(contentType); + } catch { + return new MimeType('text/plain'); + } } From 2db72fe6efbc8ff41565783775c246919989fcf3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 25 Feb 2025 06:10:35 -0800 Subject: [PATCH 075/996] Fix WS duplication from context menu --- src-web/commands/duplicateWebsocketRequest.ts | 5 ++--- src-web/components/Workspace.tsx | 2 +- .../sidebar/SidebarItemContextMenu.tsx | 20 +++++++++++++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src-web/commands/duplicateWebsocketRequest.ts b/src-web/commands/duplicateWebsocketRequest.ts index 7f5ac9997..867626b5f 100644 --- a/src-web/commands/duplicateWebsocketRequest.ts +++ b/src-web/commands/duplicateWebsocketRequest.ts @@ -1,12 +1,11 @@ -import type { WebsocketRequest } from '@yaakapp-internal/models'; import { duplicateWebsocketRequest as cmdDuplicateWebsocketRequest } from '@yaakapp-internal/ws'; import { createFastMutation } from '../hooks/useFastMutation'; import { router } from '../lib/router'; export const duplicateWebsocketRequest = createFastMutation({ mutationKey: ['delete_websocket_connection'], - mutationFn: async function (request: WebsocketRequest) { - return cmdDuplicateWebsocketRequest(request.id); + mutationFn: async function (requestId: string) { + return cmdDuplicateWebsocketRequest(requestId); }, onSuccess: async (request) => { await router.navigate({ diff --git a/src-web/components/Workspace.tsx b/src-web/components/Workspace.tsx index 9a2d22549..79b704cb3 100644 --- a/src-web/components/Workspace.tsx +++ b/src-web/components/Workspace.tsx @@ -261,7 +261,7 @@ function useGlobalWorkspaceHooks() { } else if (activeRequest.model === 'grpc_request') { await duplicateGrpcRequest.mutateAsync(); } else if (activeRequest.model === 'websocket_request') { - await duplicateWebsocketRequest.mutateAsync(activeRequest); + await duplicateWebsocketRequest.mutateAsync(activeRequest.id); } else { // eslint-disable-next-line @typescript-eslint/no-explicit-any throw new Error('Failed to duplicate invalid request model: ' + (activeRequest as any).model); diff --git a/src-web/components/sidebar/SidebarItemContextMenu.tsx b/src-web/components/sidebar/SidebarItemContextMenu.tsx index 53fa09492..6c4b743c8 100644 --- a/src-web/components/sidebar/SidebarItemContextMenu.tsx +++ b/src-web/components/sidebar/SidebarItemContextMenu.tsx @@ -1,11 +1,13 @@ import React, { useMemo } from 'react'; +import { duplicateWebsocketRequest } from '../../commands/duplicateWebsocketRequest'; import { useCreateDropdownItems } from '../../hooks/useCreateDropdownItems'; -import { useDeleteFolder } from '../../hooks/useDeleteFolder'; import { useDeleteAnyRequest } from '../../hooks/useDeleteAnyRequest'; +import { useDeleteFolder } from '../../hooks/useDeleteFolder'; import { useDuplicateFolder } from '../../hooks/useDuplicateFolder'; import { useDuplicateGrpcRequest } from '../../hooks/useDuplicateGrpcRequest'; import { useDuplicateHttpRequest } from '../../hooks/useDuplicateHttpRequest'; import { useHttpRequestActions } from '../../hooks/useHttpRequestActions'; +import { getHttpRequest } from '../../hooks/useHttpRequests'; import { useMoveToWorkspace } from '../../hooks/useMoveToWorkspace'; import { useRenameRequest } from '../../hooks/useRenameRequest'; import { useSendAnyHttpRequest } from '../../hooks/useSendAnyHttpRequest'; @@ -18,7 +20,6 @@ import { ContextMenu } from '../core/Dropdown'; import { Icon } from '../core/Icon'; import { FolderSettingsDialog } from '../FolderSettingsDialog'; import type { SidebarTreeNode } from './Sidebar'; -import { getHttpRequest } from '../../hooks/useHttpRequests'; interface Props { child: SidebarTreeNode; @@ -110,10 +111,17 @@ export function SidebarItemContextMenu({ child, show, close }: Props) { hotKeyAction: 'http_request.duplicate', hotKeyLabelOnly: true, // Would trigger for every request (bad) leftSlot: , - onSelect: () => - child.model === 'http_request' - ? duplicateHttpRequest.mutate() - : duplicateGrpcRequest.mutate(), + onSelect: () => { + if (child.model === 'http_request') { + duplicateHttpRequest.mutate(); + } else if (child.model === 'grpc_request') { + duplicateGrpcRequest.mutate(); + } else if (child.model === 'websocket_request') { + duplicateWebsocketRequest.mutate(child.id); + } else { + throw new Error('Cannot duplicate invalid model: ' + child.model); + } + }, }, { label: 'Move', From 7af8c95fead496f543a1680f67de5ad01de663cc Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 25 Feb 2025 06:54:30 -0800 Subject: [PATCH 076/996] Allow opening workspace if sync dir not empty --- src-web/commands/openWorkspaceFromSyncDir.tsx | 13 +----- src-web/components/CreateWorkspaceDialog.tsx | 4 +- .../components/SyncToFilesystemSetting.tsx | 42 ++++++++++++++----- .../components/WorkspaceActionsDropdown.tsx | 12 +++++- .../components/WorkspaceSettingsDialog.tsx | 1 + 5 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src-web/commands/openWorkspaceFromSyncDir.tsx b/src-web/commands/openWorkspaceFromSyncDir.tsx index 2b79c1aa5..ba354d122 100644 --- a/src-web/commands/openWorkspaceFromSyncDir.tsx +++ b/src-web/commands/openWorkspaceFromSyncDir.tsx @@ -1,20 +1,11 @@ -import { open } from '@tauri-apps/plugin-dialog'; import { applySync, calculateSyncFsOnly } from '@yaakapp-internal/sync'; import { createFastMutation } from '../hooks/useFastMutation'; import { showSimpleAlert } from '../lib/alert'; import { router } from '../lib/router'; -export const openWorkspaceFromSyncDir = createFastMutation({ +export const openWorkspaceFromSyncDir = createFastMutation({ mutationKey: [], - mutationFn: async () => { - const dir = await open({ - title: 'Select Workspace Directory', - directory: true, - multiple: false, - }); - - if (dir == null) return; - + mutationFn: async (dir) => { const ops = await calculateSyncFsOnly(dir); const workspace = ops diff --git a/src-web/components/CreateWorkspaceDialog.tsx b/src-web/components/CreateWorkspaceDialog.tsx index 2b80f4db7..c15015609 100644 --- a/src-web/components/CreateWorkspaceDialog.tsx +++ b/src-web/components/CreateWorkspaceDialog.tsx @@ -20,7 +20,7 @@ export function CreateWorkspaceDialog({ hide }: Props) { const [syncConfig, setSyncConfig] = useState<{ filePath: string | null; initGit?: boolean; - }>({ filePath: null, initGit: true }); + }>({ filePath: null, initGit: false }); return ( +
+ + ) : ( + + Sync workspace data to folder as plain text files, ideal for backup and Git + collaboration. Environments are excluded in order to keep your secrets private. + + )} { if (filePath != null) { const files = await readDir(filePath); - if (files.length > 0 && !allowNonEmptyDirectory) { - setError('The directory must be empty'); + if (files.length > 0) { + setIsNonEmpty(filePath); return; } } + setIsNonEmpty(null); onChange({ ...value, filePath }); }} /> diff --git a/src-web/components/WorkspaceActionsDropdown.tsx b/src-web/components/WorkspaceActionsDropdown.tsx index 15449cb75..316d9300b 100644 --- a/src-web/components/WorkspaceActionsDropdown.tsx +++ b/src-web/components/WorkspaceActionsDropdown.tsx @@ -1,3 +1,4 @@ +import {open} from "@tauri-apps/plugin-dialog"; import { revealItemInDir } from '@tauri-apps/plugin-opener'; import classNames from 'classnames'; import { memo, useCallback, useMemo } from 'react'; @@ -75,7 +76,16 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({ { label: 'Open Existing Workspace', leftSlot: , - onSelect: openWorkspaceFromSyncDir.mutate, + onSelect: async () => { + const dir = await open({ + title: 'Select Workspace Directory', + directory: true, + multiple: false, + }); + + if (dir == null) return; + openWorkspaceFromSyncDir.mutate(dir); + }, }, ]; diff --git a/src-web/components/WorkspaceSettingsDialog.tsx b/src-web/components/WorkspaceSettingsDialog.tsx index 05b406b46..5d1d900b7 100644 --- a/src-web/components/WorkspaceSettingsDialog.tsx +++ b/src-web/components/WorkspaceSettingsDialog.tsx @@ -63,6 +63,7 @@ export function WorkspaceSettingsDialog({ workspaceId, hide, openSyncMenu }: Pro { upsertWorkspaceMeta.mutate({ ...workspaceMeta, settingSyncDir: filePath }); }} From 80de232beca720ad7c59b9d2799fd9aae965ee15 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 25 Feb 2025 19:52:57 -0800 Subject: [PATCH 077/996] Fix dropdown button icon --- src-web/components/core/Button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-web/components/core/Button.tsx b/src-web/components/core/Button.tsx index c229e87a9..35f08e334 100644 --- a/src-web/components/core/Button.tsx +++ b/src-web/components/core/Button.tsx @@ -128,7 +128,7 @@ export const Button = forwardRef(function Button {children}
{rightSlot &&
{rightSlot}
} - {forDropdown && } + {forDropdown && } ); }); From eb8153f40960b225ee3e7447c53652176e3ec798 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 25 Feb 2025 22:16:55 -0800 Subject: [PATCH 078/996] Better trial activation flows --- src-tauri/yaak-license/index.ts | 1 + src-web/components/LicenseBadge.tsx | 2 +- .../components/Settings/SettingsLicense.tsx | 31 +++++++------------ src-web/components/SettingsDropdown.tsx | 10 ++++++ src-web/components/core/Dropdown.tsx | 3 +- src-web/components/core/Icon.tsx | 1 + 6 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src-tauri/yaak-license/index.ts b/src-tauri/yaak-license/index.ts index eedd5167e..42d82f587 100644 --- a/src-tauri/yaak-license/index.ts +++ b/src-tauri/yaak-license/index.ts @@ -26,6 +26,7 @@ export function useLicense() { const CHECK_QUERY_KEY = ['license.check']; const check = useQuery({ + refetchInterval: 1000 * 60 * 60 * 12, // Refetch every 12 hours queryKey: CHECK_QUERY_KEY, queryFn: () => invoke('plugin:yaak-license|check'), }); diff --git a/src-web/components/LicenseBadge.tsx b/src-web/components/LicenseBadge.tsx index 13566799f..bd3e250c7 100644 --- a/src-web/components/LicenseBadge.tsx +++ b/src-web/components/LicenseBadge.tsx @@ -65,7 +65,7 @@ export function LicenseBadge() { if (check.data.type === 'trialing') { await setLicenseDetails((v) => ({ ...v, - dismissedTrial: true, + hasDismissedTrial: true, })); } openSettings.mutate(SettingsTab.License); diff --git a/src-web/components/Settings/SettingsLicense.tsx b/src-web/components/Settings/SettingsLicense.tsx index e88760efa..759d820b7 100644 --- a/src-web/components/Settings/SettingsLicense.tsx +++ b/src-web/components/Settings/SettingsLicense.tsx @@ -1,9 +1,10 @@ import { openUrl } from '@tauri-apps/plugin-opener'; import { useLicense } from '@yaakapp-internal/license'; -import { formatDistanceToNowStrict } from 'date-fns'; +import { differenceInDays } from 'date-fns'; import React, { useState } from 'react'; import { useLicenseConfirmation } from '../../hooks/useLicenseConfirmation'; import { useToggle } from '../../hooks/useToggle'; +import { pluralizeCount } from '../../lib/pluralize'; import { Banner } from '../core/Banner'; import { Button } from '../core/Button'; import { Checkbox } from '../core/Checkbox'; @@ -32,8 +33,12 @@ export function SettingsLicense() { ) : check.data?.type == 'trialing' ? (

- {formatDistanceToNowStrict(check.data.end)} days remaining on your - commercial use trial + You have{' '} + + {pluralizeCount('day', differenceInDays(check.data.end, new Date()))} remaining + {' '} + on your commercial use trial. Once the trial ends, Yaak will be limited to personal use + until a license is activated.

) : check.data?.type == 'personal_use' && !licenseDetails?.confirmedPersonalUse ? ( @@ -76,12 +81,7 @@ export function SettingsLicense() { {check.data?.type === 'commercial_use' ? ( - diff --git a/src-web/components/SettingsDropdown.tsx b/src-web/components/SettingsDropdown.tsx index ab73951c9..a7d00b4e2 100644 --- a/src-web/components/SettingsDropdown.tsx +++ b/src-web/components/SettingsDropdown.tsx @@ -1,4 +1,5 @@ import { openUrl } from '@tauri-apps/plugin-opener'; +import { useLicense } from '@yaakapp-internal/license'; import { useRef } from 'react'; import { openSettings } from '../commands/openSettings'; import { useAppInfo } from '../hooks/useAppInfo'; @@ -12,6 +13,7 @@ import { Dropdown } from './core/Dropdown'; import { Icon } from './core/Icon'; import { IconButton } from './core/IconButton'; import { KeyboardShortcutsDialog } from './KeyboardShortcutsDialog'; +import { SettingsTab } from './Settings/SettingsTab'; export function SettingsDropdown() { const importData = useImportData(); @@ -19,6 +21,7 @@ export function SettingsDropdown() { const appInfo = useAppInfo(); const dropdownRef = useRef(null); const checkForUpdates = useCheckForUpdates(); + const { check } = useLicense(); useListenToTauriEvent('settings', () => openSettings.mutate(null)); @@ -56,6 +59,13 @@ export function SettingsDropdown() { onSelect: () => exportData.mutate(), }, { type: 'separator', label: `Yaak v${appInfo.version}` }, + { + label: 'Purchase License', + color: 'success', + hidden: check.data == null || check.data.type === 'commercial_use', + leftSlot: , + onSelect: () => openSettings.mutate(SettingsTab.License), + }, { label: 'Check for Updates', leftSlot: , diff --git a/src-web/components/core/Dropdown.tsx b/src-web/components/core/Dropdown.tsx index 31bbb1175..0c4f20dd8 100644 --- a/src-web/components/core/Dropdown.tsx +++ b/src-web/components/core/Dropdown.tsx @@ -55,7 +55,7 @@ export type DropdownItemDefault = { label: ReactNode; hotKeyAction?: HotkeyAction; hotKeyLabelOnly?: boolean; - color?: 'default' | 'danger' | 'info' | 'warning' | 'notice' | 'success'; + color?: 'default' | 'primary' | 'danger' | 'info' | 'warning' | 'notice' | 'success'; disabled?: boolean; hidden?: boolean; leftSlot?: ReactNode; @@ -645,6 +645,7 @@ function MenuItem({ className, focused, onFocus, item, onSelect, ...props }: Men 'min-w-[8rem] outline-none px-2 mx-1.5 flex whitespace-nowrap', 'focus:bg-surface-highlight focus:text rounded', item.color === 'danger' && '!text-danger', + item.color === 'primary' && '!text-primary', item.color === 'success' && '!text-success', item.color === 'warning' && '!text-warning', item.color === 'notice' && '!text-notice', diff --git a/src-web/components/core/Icon.tsx b/src-web/components/core/Icon.tsx index 9928268e4..e47cfee52 100644 --- a/src-web/components/core/Icon.tsx +++ b/src-web/components/core/Icon.tsx @@ -8,6 +8,7 @@ const icons = { alert_triangle: lucide.AlertTriangleIcon, archive: lucide.ArchiveIcon, arrow_big_down_dash: lucide.ArrowBigDownDashIcon, + circle_dollar_sign: lucide.CircleDollarSignIcon, arrow_right_circle: lucide.ArrowRightCircleIcon, arrow_big_left_dash: lucide.ArrowBigLeftDashIcon, arrow_big_right: lucide.ArrowBigRightIcon, From 9ead45d67abc9b1183c8edc6d68847c5057bf602 Mon Sep 17 00:00:00 2001 From: Hao Xiang Date: Sun, 2 Mar 2025 21:51:19 +0800 Subject: [PATCH 079/996] fix plugin manager listen addr (#177) --- src-tauri/yaak-plugins/src/manager.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src-tauri/yaak-plugins/src/manager.rs b/src-tauri/yaak-plugins/src/manager.rs index 371c40887..82255adf6 100644 --- a/src-tauri/yaak-plugins/src/manager.rs +++ b/src-tauri/yaak-plugins/src/manager.rs @@ -79,8 +79,8 @@ impl PluginManager { }); let listen_addr = match option_env!("YAAK_PLUGIN_SERVER_PORT") { - Some(port) => format!("localhost:{port}"), - None => "localhost:0".to_string(), + Some(port) => format!("127.0.0.1:{port}"), + None => "127.0.0.1:0".to_string(), }; let listener = tauri::async_runtime::block_on(async move { TcpListener::bind(listen_addr).await.expect("Failed to bind TCP listener") From 7a1a0689b03d127dc36bc5cd4694d8a2fcfac5bc Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 5 Mar 2025 07:13:19 -0800 Subject: [PATCH 080/996] Add ability to deactivate license --- src-tauri/gen/schemas/acl-manifests.json | 2 +- src-tauri/gen/schemas/desktop-schema.json | 10 +++ src-tauri/gen/schemas/macOS-schema.json | 10 +++ src-tauri/yaak-license/bindings/license.ts | 2 + src-tauri/yaak-license/build.rs | 2 +- src-tauri/yaak-license/index.ts | 8 ++ .../autogenerated/commands/deactivate.toml | 13 +++ .../permissions/autogenerated/reference.md | 27 +++++++ .../yaak-license/permissions/default.toml | 2 +- .../permissions/schemas/schema.json | 10 +++ src-tauri/yaak-license/src/commands.rs | 20 ++++- src-tauri/yaak-license/src/lib.rs | 6 +- src-tauri/yaak-license/src/license.rs | 79 ++++++++++++++----- src-tauri/yaak-models/src/queries.rs | 25 ++++++ src-web/components/LicenseBadge.tsx | 26 ++++-- .../components/Settings/SettingsLicense.tsx | 12 +-- 16 files changed, 218 insertions(+), 36 deletions(-) create mode 100644 src-tauri/yaak-license/permissions/autogenerated/commands/deactivate.toml diff --git a/src-tauri/gen/schemas/acl-manifests.json b/src-tauri/gen/schemas/acl-manifests.json index 83458de43..26c087fa2 100644 --- a/src-tauri/gen/schemas/acl-manifests.json +++ b/src-tauri/gen/schemas/acl-manifests.json @@ -1 +1 @@ -{"clipboard-manager":{"default_permission":{"identifier":"default","description":"No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n","permissions":[]},"permissions":{"allow-clear":{"identifier":"allow-clear","description":"Enables the clear command without any pre-configured scope.","commands":{"allow":["clear"],"deny":[]}},"allow-read-image":{"identifier":"allow-read-image","description":"Enables the read_image command without any pre-configured scope.","commands":{"allow":["read_image"],"deny":[]}},"allow-read-text":{"identifier":"allow-read-text","description":"Enables the read_text command without any pre-configured scope.","commands":{"allow":["read_text"],"deny":[]}},"allow-write-html":{"identifier":"allow-write-html","description":"Enables the write_html command without any pre-configured scope.","commands":{"allow":["write_html"],"deny":[]}},"allow-write-image":{"identifier":"allow-write-image","description":"Enables the write_image command without any pre-configured scope.","commands":{"allow":["write_image"],"deny":[]}},"allow-write-text":{"identifier":"allow-write-text","description":"Enables the write_text command without any pre-configured scope.","commands":{"allow":["write_text"],"deny":[]}},"deny-clear":{"identifier":"deny-clear","description":"Denies the clear command without any pre-configured scope.","commands":{"allow":[],"deny":["clear"]}},"deny-read-image":{"identifier":"deny-read-image","description":"Denies the read_image command without any pre-configured scope.","commands":{"allow":[],"deny":["read_image"]}},"deny-read-text":{"identifier":"deny-read-text","description":"Denies the read_text command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text"]}},"deny-write-html":{"identifier":"deny-write-html","description":"Denies the write_html command without any pre-configured scope.","commands":{"allow":[],"deny":["write_html"]}},"deny-write-image":{"identifier":"deny-write-image","description":"Denies the write_image command without any pre-configured scope.","commands":{"allow":[],"deny":["write_image"]}},"deny-write-text":{"identifier":"deny-write-text","description":"Denies the write_text command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text"]}}},"permission_sets":{},"global_scope_schema":null},"core":{"default_permission":{"identifier":"default","description":"Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-ask","allow-confirm","allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope.","commands":{"allow":["ask"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope.","commands":{"allow":["confirm"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope.","commands":{"allow":[],"deny":["ask"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope.","commands":{"allow":[],"deny":["confirm"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"fs":{"default_permission":{"identifier":"default","description":"This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n","permissions":["create-app-specific-dirs","read-app-specific-dirs-recursive","deny-default"]},"permissions":{"allow-copy-file":{"identifier":"allow-copy-file","description":"Enables the copy_file command without any pre-configured scope.","commands":{"allow":["copy_file"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-exists":{"identifier":"allow-exists","description":"Enables the exists command without any pre-configured scope.","commands":{"allow":["exists"],"deny":[]}},"allow-fstat":{"identifier":"allow-fstat","description":"Enables the fstat command without any pre-configured scope.","commands":{"allow":["fstat"],"deny":[]}},"allow-ftruncate":{"identifier":"allow-ftruncate","description":"Enables the ftruncate command without any pre-configured scope.","commands":{"allow":["ftruncate"],"deny":[]}},"allow-lstat":{"identifier":"allow-lstat","description":"Enables the lstat command without any pre-configured scope.","commands":{"allow":["lstat"],"deny":[]}},"allow-mkdir":{"identifier":"allow-mkdir","description":"Enables the mkdir command without any pre-configured scope.","commands":{"allow":["mkdir"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-read":{"identifier":"allow-read","description":"Enables the read command without any pre-configured scope.","commands":{"allow":["read"],"deny":[]}},"allow-read-dir":{"identifier":"allow-read-dir","description":"Enables the read_dir command without any pre-configured scope.","commands":{"allow":["read_dir"],"deny":[]}},"allow-read-file":{"identifier":"allow-read-file","description":"Enables the read_file command without any pre-configured scope.","commands":{"allow":["read_file"],"deny":[]}},"allow-read-text-file":{"identifier":"allow-read-text-file","description":"Enables the read_text_file command without any pre-configured scope.","commands":{"allow":["read_text_file"],"deny":[]}},"allow-read-text-file-lines":{"identifier":"allow-read-text-file-lines","description":"Enables the read_text_file_lines command without any pre-configured scope.","commands":{"allow":["read_text_file_lines","read_text_file_lines_next"],"deny":[]}},"allow-read-text-file-lines-next":{"identifier":"allow-read-text-file-lines-next","description":"Enables the read_text_file_lines_next command without any pre-configured scope.","commands":{"allow":["read_text_file_lines_next"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-rename":{"identifier":"allow-rename","description":"Enables the rename command without any pre-configured scope.","commands":{"allow":["rename"],"deny":[]}},"allow-seek":{"identifier":"allow-seek","description":"Enables the seek command without any pre-configured scope.","commands":{"allow":["seek"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"allow-stat":{"identifier":"allow-stat","description":"Enables the stat command without any pre-configured scope.","commands":{"allow":["stat"],"deny":[]}},"allow-truncate":{"identifier":"allow-truncate","description":"Enables the truncate command without any pre-configured scope.","commands":{"allow":["truncate"],"deny":[]}},"allow-unwatch":{"identifier":"allow-unwatch","description":"Enables the unwatch command without any pre-configured scope.","commands":{"allow":["unwatch"],"deny":[]}},"allow-watch":{"identifier":"allow-watch","description":"Enables the watch command without any pre-configured scope.","commands":{"allow":["watch"],"deny":[]}},"allow-write":{"identifier":"allow-write","description":"Enables the write command without any pre-configured scope.","commands":{"allow":["write"],"deny":[]}},"allow-write-file":{"identifier":"allow-write-file","description":"Enables the write_file command without any pre-configured scope.","commands":{"allow":["write_file","open","write"],"deny":[]}},"allow-write-text-file":{"identifier":"allow-write-text-file","description":"Enables the write_text_file command without any pre-configured scope.","commands":{"allow":["write_text_file"],"deny":[]}},"create-app-specific-dirs":{"identifier":"create-app-specific-dirs","description":"This permissions allows to create the application specific directories.\n","commands":{"allow":["mkdir","scope-app-index"],"deny":[]}},"deny-copy-file":{"identifier":"deny-copy-file","description":"Denies the copy_file command without any pre-configured scope.","commands":{"allow":[],"deny":["copy_file"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-exists":{"identifier":"deny-exists","description":"Denies the exists command without any pre-configured scope.","commands":{"allow":[],"deny":["exists"]}},"deny-fstat":{"identifier":"deny-fstat","description":"Denies the fstat command without any pre-configured scope.","commands":{"allow":[],"deny":["fstat"]}},"deny-ftruncate":{"identifier":"deny-ftruncate","description":"Denies the ftruncate command without any pre-configured scope.","commands":{"allow":[],"deny":["ftruncate"]}},"deny-lstat":{"identifier":"deny-lstat","description":"Denies the lstat command without any pre-configured scope.","commands":{"allow":[],"deny":["lstat"]}},"deny-mkdir":{"identifier":"deny-mkdir","description":"Denies the mkdir command without any pre-configured scope.","commands":{"allow":[],"deny":["mkdir"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-read":{"identifier":"deny-read","description":"Denies the read command without any pre-configured scope.","commands":{"allow":[],"deny":["read"]}},"deny-read-dir":{"identifier":"deny-read-dir","description":"Denies the read_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["read_dir"]}},"deny-read-file":{"identifier":"deny-read-file","description":"Denies the read_file command without any pre-configured scope.","commands":{"allow":[],"deny":["read_file"]}},"deny-read-text-file":{"identifier":"deny-read-text-file","description":"Denies the read_text_file command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file"]}},"deny-read-text-file-lines":{"identifier":"deny-read-text-file-lines","description":"Denies the read_text_file_lines command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file_lines"]}},"deny-read-text-file-lines-next":{"identifier":"deny-read-text-file-lines-next","description":"Denies the read_text_file_lines_next command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file_lines_next"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-rename":{"identifier":"deny-rename","description":"Denies the rename command without any pre-configured scope.","commands":{"allow":[],"deny":["rename"]}},"deny-seek":{"identifier":"deny-seek","description":"Denies the seek command without any pre-configured scope.","commands":{"allow":[],"deny":["seek"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}},"deny-stat":{"identifier":"deny-stat","description":"Denies the stat command without any pre-configured scope.","commands":{"allow":[],"deny":["stat"]}},"deny-truncate":{"identifier":"deny-truncate","description":"Denies the truncate command without any pre-configured scope.","commands":{"allow":[],"deny":["truncate"]}},"deny-unwatch":{"identifier":"deny-unwatch","description":"Denies the unwatch command without any pre-configured scope.","commands":{"allow":[],"deny":["unwatch"]}},"deny-watch":{"identifier":"deny-watch","description":"Denies the watch command without any pre-configured scope.","commands":{"allow":[],"deny":["watch"]}},"deny-webview-data-linux":{"identifier":"deny-webview-data-linux","description":"This denies read access to the\n`$APPLOCALDATA` folder on linux as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.","commands":{"allow":[],"deny":[]}},"deny-webview-data-windows":{"identifier":"deny-webview-data-windows","description":"This denies read access to the\n`$APPLOCALDATA/EBWebView` folder on windows as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.","commands":{"allow":[],"deny":[]}},"deny-write":{"identifier":"deny-write","description":"Denies the write command without any pre-configured scope.","commands":{"allow":[],"deny":["write"]}},"deny-write-file":{"identifier":"deny-write-file","description":"Denies the write_file command without any pre-configured scope.","commands":{"allow":[],"deny":["write_file"]}},"deny-write-text-file":{"identifier":"deny-write-text-file","description":"Denies the write_text_file command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text_file"]}},"read-all":{"identifier":"read-all","description":"This enables all read related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","read_file","read","open","read_text_file","read_text_file_lines","read_text_file_lines_next","seek","stat","lstat","fstat","exists","watch","unwatch"],"deny":[]}},"read-app-specific-dirs-recursive":{"identifier":"read-app-specific-dirs-recursive","description":"This permission allows recursive read functionality on the application\nspecific base directories. \n","commands":{"allow":["read_dir","read_file","read_text_file","read_text_file_lines","read_text_file_lines_next","exists","scope-app-recursive"],"deny":[]}},"read-dirs":{"identifier":"read-dirs","description":"This enables directory read and file metadata related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","stat","lstat","fstat","exists"],"deny":[]}},"read-files":{"identifier":"read-files","description":"This enables file read related commands without any pre-configured accessible paths.","commands":{"allow":["read_file","read","open","read_text_file","read_text_file_lines","read_text_file_lines_next","seek","stat","lstat","fstat","exists"],"deny":[]}},"read-meta":{"identifier":"read-meta","description":"This enables all index or metadata related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","stat","lstat","fstat","exists","size"],"deny":[]}},"scope":{"identifier":"scope","description":"An empty permission you can use to modify the global scope.","commands":{"allow":[],"deny":[]}},"scope-app":{"identifier":"scope-app","description":"This scope permits access to all files and list content of top level directories in the application folders.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/*"},{"path":"$APPDATA"},{"path":"$APPDATA/*"},{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/*"},{"path":"$APPCACHE"},{"path":"$APPCACHE/*"},{"path":"$APPLOG"},{"path":"$APPLOG/*"}]}},"scope-app-index":{"identifier":"scope-app-index","description":"This scope permits to list all files and folders in the application directories.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPDATA"},{"path":"$APPLOCALDATA"},{"path":"$APPCACHE"},{"path":"$APPLOG"}]}},"scope-app-recursive":{"identifier":"scope-app-recursive","description":"This scope permits recursive access to the complete application folders, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/**"},{"path":"$APPDATA"},{"path":"$APPDATA/**"},{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/**"},{"path":"$APPCACHE"},{"path":"$APPCACHE/**"},{"path":"$APPLOG"},{"path":"$APPLOG/**"}]}},"scope-appcache":{"identifier":"scope-appcache","description":"This scope permits access to all files and list content of top level directories in the `$APPCACHE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"},{"path":"$APPCACHE/*"}]}},"scope-appcache-index":{"identifier":"scope-appcache-index","description":"This scope permits to list all files and folders in the `$APPCACHE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"}]}},"scope-appcache-recursive":{"identifier":"scope-appcache-recursive","description":"This scope permits recursive access to the complete `$APPCACHE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"},{"path":"$APPCACHE/**"}]}},"scope-appconfig":{"identifier":"scope-appconfig","description":"This scope permits access to all files and list content of top level directories in the `$APPCONFIG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/*"}]}},"scope-appconfig-index":{"identifier":"scope-appconfig-index","description":"This scope permits to list all files and folders in the `$APPCONFIG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"}]}},"scope-appconfig-recursive":{"identifier":"scope-appconfig-recursive","description":"This scope permits recursive access to the complete `$APPCONFIG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/**"}]}},"scope-appdata":{"identifier":"scope-appdata","description":"This scope permits access to all files and list content of top level directories in the `$APPDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"},{"path":"$APPDATA/*"}]}},"scope-appdata-index":{"identifier":"scope-appdata-index","description":"This scope permits to list all files and folders in the `$APPDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"}]}},"scope-appdata-recursive":{"identifier":"scope-appdata-recursive","description":"This scope permits recursive access to the complete `$APPDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]}},"scope-applocaldata":{"identifier":"scope-applocaldata","description":"This scope permits access to all files and list content of top level directories in the `$APPLOCALDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/*"}]}},"scope-applocaldata-index":{"identifier":"scope-applocaldata-index","description":"This scope permits to list all files and folders in the `$APPLOCALDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"}]}},"scope-applocaldata-recursive":{"identifier":"scope-applocaldata-recursive","description":"This scope permits recursive access to the complete `$APPLOCALDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/**"}]}},"scope-applog":{"identifier":"scope-applog","description":"This scope permits access to all files and list content of top level directories in the `$APPLOG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"},{"path":"$APPLOG/*"}]}},"scope-applog-index":{"identifier":"scope-applog-index","description":"This scope permits to list all files and folders in the `$APPLOG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"}]}},"scope-applog-recursive":{"identifier":"scope-applog-recursive","description":"This scope permits recursive access to the complete `$APPLOG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"},{"path":"$APPLOG/**"}]}},"scope-audio":{"identifier":"scope-audio","description":"This scope permits access to all files and list content of top level directories in the `$AUDIO` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"},{"path":"$AUDIO/*"}]}},"scope-audio-index":{"identifier":"scope-audio-index","description":"This scope permits to list all files and folders in the `$AUDIO`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"}]}},"scope-audio-recursive":{"identifier":"scope-audio-recursive","description":"This scope permits recursive access to the complete `$AUDIO` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"},{"path":"$AUDIO/**"}]}},"scope-cache":{"identifier":"scope-cache","description":"This scope permits access to all files and list content of top level directories in the `$CACHE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"},{"path":"$CACHE/*"}]}},"scope-cache-index":{"identifier":"scope-cache-index","description":"This scope permits to list all files and folders in the `$CACHE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"}]}},"scope-cache-recursive":{"identifier":"scope-cache-recursive","description":"This scope permits recursive access to the complete `$CACHE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"},{"path":"$CACHE/**"}]}},"scope-config":{"identifier":"scope-config","description":"This scope permits access to all files and list content of top level directories in the `$CONFIG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"},{"path":"$CONFIG/*"}]}},"scope-config-index":{"identifier":"scope-config-index","description":"This scope permits to list all files and folders in the `$CONFIG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"}]}},"scope-config-recursive":{"identifier":"scope-config-recursive","description":"This scope permits recursive access to the complete `$CONFIG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"},{"path":"$CONFIG/**"}]}},"scope-data":{"identifier":"scope-data","description":"This scope permits access to all files and list content of top level directories in the `$DATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"},{"path":"$DATA/*"}]}},"scope-data-index":{"identifier":"scope-data-index","description":"This scope permits to list all files and folders in the `$DATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"}]}},"scope-data-recursive":{"identifier":"scope-data-recursive","description":"This scope permits recursive access to the complete `$DATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"},{"path":"$DATA/**"}]}},"scope-desktop":{"identifier":"scope-desktop","description":"This scope permits access to all files and list content of top level directories in the `$DESKTOP` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"},{"path":"$DESKTOP/*"}]}},"scope-desktop-index":{"identifier":"scope-desktop-index","description":"This scope permits to list all files and folders in the `$DESKTOP`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"}]}},"scope-desktop-recursive":{"identifier":"scope-desktop-recursive","description":"This scope permits recursive access to the complete `$DESKTOP` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"},{"path":"$DESKTOP/**"}]}},"scope-document":{"identifier":"scope-document","description":"This scope permits access to all files and list content of top level directories in the `$DOCUMENT` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"},{"path":"$DOCUMENT/*"}]}},"scope-document-index":{"identifier":"scope-document-index","description":"This scope permits to list all files and folders in the `$DOCUMENT`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"}]}},"scope-document-recursive":{"identifier":"scope-document-recursive","description":"This scope permits recursive access to the complete `$DOCUMENT` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"},{"path":"$DOCUMENT/**"}]}},"scope-download":{"identifier":"scope-download","description":"This scope permits access to all files and list content of top level directories in the `$DOWNLOAD` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"},{"path":"$DOWNLOAD/*"}]}},"scope-download-index":{"identifier":"scope-download-index","description":"This scope permits to list all files and folders in the `$DOWNLOAD`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"}]}},"scope-download-recursive":{"identifier":"scope-download-recursive","description":"This scope permits recursive access to the complete `$DOWNLOAD` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"},{"path":"$DOWNLOAD/**"}]}},"scope-exe":{"identifier":"scope-exe","description":"This scope permits access to all files and list content of top level directories in the `$EXE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"},{"path":"$EXE/*"}]}},"scope-exe-index":{"identifier":"scope-exe-index","description":"This scope permits to list all files and folders in the `$EXE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"}]}},"scope-exe-recursive":{"identifier":"scope-exe-recursive","description":"This scope permits recursive access to the complete `$EXE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"},{"path":"$EXE/**"}]}},"scope-font":{"identifier":"scope-font","description":"This scope permits access to all files and list content of top level directories in the `$FONT` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"},{"path":"$FONT/*"}]}},"scope-font-index":{"identifier":"scope-font-index","description":"This scope permits to list all files and folders in the `$FONT`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"}]}},"scope-font-recursive":{"identifier":"scope-font-recursive","description":"This scope permits recursive access to the complete `$FONT` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"},{"path":"$FONT/**"}]}},"scope-home":{"identifier":"scope-home","description":"This scope permits access to all files and list content of top level directories in the `$HOME` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"},{"path":"$HOME/*"}]}},"scope-home-index":{"identifier":"scope-home-index","description":"This scope permits to list all files and folders in the `$HOME`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"}]}},"scope-home-recursive":{"identifier":"scope-home-recursive","description":"This scope permits recursive access to the complete `$HOME` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"},{"path":"$HOME/**"}]}},"scope-localdata":{"identifier":"scope-localdata","description":"This scope permits access to all files and list content of top level directories in the `$LOCALDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"},{"path":"$LOCALDATA/*"}]}},"scope-localdata-index":{"identifier":"scope-localdata-index","description":"This scope permits to list all files and folders in the `$LOCALDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"}]}},"scope-localdata-recursive":{"identifier":"scope-localdata-recursive","description":"This scope permits recursive access to the complete `$LOCALDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"},{"path":"$LOCALDATA/**"}]}},"scope-log":{"identifier":"scope-log","description":"This scope permits access to all files and list content of top level directories in the `$LOG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"},{"path":"$LOG/*"}]}},"scope-log-index":{"identifier":"scope-log-index","description":"This scope permits to list all files and folders in the `$LOG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"}]}},"scope-log-recursive":{"identifier":"scope-log-recursive","description":"This scope permits recursive access to the complete `$LOG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"},{"path":"$LOG/**"}]}},"scope-picture":{"identifier":"scope-picture","description":"This scope permits access to all files and list content of top level directories in the `$PICTURE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"},{"path":"$PICTURE/*"}]}},"scope-picture-index":{"identifier":"scope-picture-index","description":"This scope permits to list all files and folders in the `$PICTURE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"}]}},"scope-picture-recursive":{"identifier":"scope-picture-recursive","description":"This scope permits recursive access to the complete `$PICTURE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"},{"path":"$PICTURE/**"}]}},"scope-public":{"identifier":"scope-public","description":"This scope permits access to all files and list content of top level directories in the `$PUBLIC` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"},{"path":"$PUBLIC/*"}]}},"scope-public-index":{"identifier":"scope-public-index","description":"This scope permits to list all files and folders in the `$PUBLIC`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"}]}},"scope-public-recursive":{"identifier":"scope-public-recursive","description":"This scope permits recursive access to the complete `$PUBLIC` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"},{"path":"$PUBLIC/**"}]}},"scope-resource":{"identifier":"scope-resource","description":"This scope permits access to all files and list content of top level directories in the `$RESOURCE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"},{"path":"$RESOURCE/*"}]}},"scope-resource-index":{"identifier":"scope-resource-index","description":"This scope permits to list all files and folders in the `$RESOURCE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"}]}},"scope-resource-recursive":{"identifier":"scope-resource-recursive","description":"This scope permits recursive access to the complete `$RESOURCE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"},{"path":"$RESOURCE/**"}]}},"scope-runtime":{"identifier":"scope-runtime","description":"This scope permits access to all files and list content of top level directories in the `$RUNTIME` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"},{"path":"$RUNTIME/*"}]}},"scope-runtime-index":{"identifier":"scope-runtime-index","description":"This scope permits to list all files and folders in the `$RUNTIME`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"}]}},"scope-runtime-recursive":{"identifier":"scope-runtime-recursive","description":"This scope permits recursive access to the complete `$RUNTIME` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"},{"path":"$RUNTIME/**"}]}},"scope-temp":{"identifier":"scope-temp","description":"This scope permits access to all files and list content of top level directories in the `$TEMP` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"},{"path":"$TEMP/*"}]}},"scope-temp-index":{"identifier":"scope-temp-index","description":"This scope permits to list all files and folders in the `$TEMP`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"}]}},"scope-temp-recursive":{"identifier":"scope-temp-recursive","description":"This scope permits recursive access to the complete `$TEMP` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"},{"path":"$TEMP/**"}]}},"scope-template":{"identifier":"scope-template","description":"This scope permits access to all files and list content of top level directories in the `$TEMPLATE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"},{"path":"$TEMPLATE/*"}]}},"scope-template-index":{"identifier":"scope-template-index","description":"This scope permits to list all files and folders in the `$TEMPLATE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"}]}},"scope-template-recursive":{"identifier":"scope-template-recursive","description":"This scope permits recursive access to the complete `$TEMPLATE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"},{"path":"$TEMPLATE/**"}]}},"scope-video":{"identifier":"scope-video","description":"This scope permits access to all files and list content of top level directories in the `$VIDEO` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"},{"path":"$VIDEO/*"}]}},"scope-video-index":{"identifier":"scope-video-index","description":"This scope permits to list all files and folders in the `$VIDEO`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"}]}},"scope-video-recursive":{"identifier":"scope-video-recursive","description":"This scope permits recursive access to the complete `$VIDEO` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"},{"path":"$VIDEO/**"}]}},"write-all":{"identifier":"write-all","description":"This enables all write related commands without any pre-configured accessible paths.","commands":{"allow":["mkdir","create","copy_file","remove","rename","truncate","ftruncate","write","write_file","write_text_file"],"deny":[]}},"write-files":{"identifier":"write-files","description":"This enables all file write related commands without any pre-configured accessible paths.","commands":{"allow":["create","copy_file","remove","rename","truncate","ftruncate","write","write_file","write_text_file"],"deny":[]}}},"permission_sets":{"allow-app-meta":{"identifier":"allow-app-meta","description":"This allows non-recursive read access to metadata of the application folders, including file listing and statistics.","permissions":["read-meta","scope-app-index"]},"allow-app-meta-recursive":{"identifier":"allow-app-meta-recursive","description":"This allows full recursive read access to metadata of the application folders, including file listing and statistics.","permissions":["read-meta","scope-app-recursive"]},"allow-app-read":{"identifier":"allow-app-read","description":"This allows non-recursive read access to the application folders.","permissions":["read-all","scope-app"]},"allow-app-read-recursive":{"identifier":"allow-app-read-recursive","description":"This allows full recursive read access to the complete application folders, files and subdirectories.","permissions":["read-all","scope-app-recursive"]},"allow-app-write":{"identifier":"allow-app-write","description":"This allows non-recursive write access to the application folders.","permissions":["write-all","scope-app"]},"allow-app-write-recursive":{"identifier":"allow-app-write-recursive","description":"This allows full recursive write access to the complete application folders, files and subdirectories.","permissions":["write-all","scope-app-recursive"]},"allow-appcache-meta":{"identifier":"allow-appcache-meta","description":"This allows non-recursive read access to metadata of the `$APPCACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-appcache-index"]},"allow-appcache-meta-recursive":{"identifier":"allow-appcache-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPCACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-appcache-recursive"]},"allow-appcache-read":{"identifier":"allow-appcache-read","description":"This allows non-recursive read access to the `$APPCACHE` folder.","permissions":["read-all","scope-appcache"]},"allow-appcache-read-recursive":{"identifier":"allow-appcache-read-recursive","description":"This allows full recursive read access to the complete `$APPCACHE` folder, files and subdirectories.","permissions":["read-all","scope-appcache-recursive"]},"allow-appcache-write":{"identifier":"allow-appcache-write","description":"This allows non-recursive write access to the `$APPCACHE` folder.","permissions":["write-all","scope-appcache"]},"allow-appcache-write-recursive":{"identifier":"allow-appcache-write-recursive","description":"This allows full recursive write access to the complete `$APPCACHE` folder, files and subdirectories.","permissions":["write-all","scope-appcache-recursive"]},"allow-appconfig-meta":{"identifier":"allow-appconfig-meta","description":"This allows non-recursive read access to metadata of the `$APPCONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-appconfig-index"]},"allow-appconfig-meta-recursive":{"identifier":"allow-appconfig-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPCONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-appconfig-recursive"]},"allow-appconfig-read":{"identifier":"allow-appconfig-read","description":"This allows non-recursive read access to the `$APPCONFIG` folder.","permissions":["read-all","scope-appconfig"]},"allow-appconfig-read-recursive":{"identifier":"allow-appconfig-read-recursive","description":"This allows full recursive read access to the complete `$APPCONFIG` folder, files and subdirectories.","permissions":["read-all","scope-appconfig-recursive"]},"allow-appconfig-write":{"identifier":"allow-appconfig-write","description":"This allows non-recursive write access to the `$APPCONFIG` folder.","permissions":["write-all","scope-appconfig"]},"allow-appconfig-write-recursive":{"identifier":"allow-appconfig-write-recursive","description":"This allows full recursive write access to the complete `$APPCONFIG` folder, files and subdirectories.","permissions":["write-all","scope-appconfig-recursive"]},"allow-appdata-meta":{"identifier":"allow-appdata-meta","description":"This allows non-recursive read access to metadata of the `$APPDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-appdata-index"]},"allow-appdata-meta-recursive":{"identifier":"allow-appdata-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-appdata-recursive"]},"allow-appdata-read":{"identifier":"allow-appdata-read","description":"This allows non-recursive read access to the `$APPDATA` folder.","permissions":["read-all","scope-appdata"]},"allow-appdata-read-recursive":{"identifier":"allow-appdata-read-recursive","description":"This allows full recursive read access to the complete `$APPDATA` folder, files and subdirectories.","permissions":["read-all","scope-appdata-recursive"]},"allow-appdata-write":{"identifier":"allow-appdata-write","description":"This allows non-recursive write access to the `$APPDATA` folder.","permissions":["write-all","scope-appdata"]},"allow-appdata-write-recursive":{"identifier":"allow-appdata-write-recursive","description":"This allows full recursive write access to the complete `$APPDATA` folder, files and subdirectories.","permissions":["write-all","scope-appdata-recursive"]},"allow-applocaldata-meta":{"identifier":"allow-applocaldata-meta","description":"This allows non-recursive read access to metadata of the `$APPLOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-applocaldata-index"]},"allow-applocaldata-meta-recursive":{"identifier":"allow-applocaldata-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPLOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-applocaldata-recursive"]},"allow-applocaldata-read":{"identifier":"allow-applocaldata-read","description":"This allows non-recursive read access to the `$APPLOCALDATA` folder.","permissions":["read-all","scope-applocaldata"]},"allow-applocaldata-read-recursive":{"identifier":"allow-applocaldata-read-recursive","description":"This allows full recursive read access to the complete `$APPLOCALDATA` folder, files and subdirectories.","permissions":["read-all","scope-applocaldata-recursive"]},"allow-applocaldata-write":{"identifier":"allow-applocaldata-write","description":"This allows non-recursive write access to the `$APPLOCALDATA` folder.","permissions":["write-all","scope-applocaldata"]},"allow-applocaldata-write-recursive":{"identifier":"allow-applocaldata-write-recursive","description":"This allows full recursive write access to the complete `$APPLOCALDATA` folder, files and subdirectories.","permissions":["write-all","scope-applocaldata-recursive"]},"allow-applog-meta":{"identifier":"allow-applog-meta","description":"This allows non-recursive read access to metadata of the `$APPLOG` folder, including file listing and statistics.","permissions":["read-meta","scope-applog-index"]},"allow-applog-meta-recursive":{"identifier":"allow-applog-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPLOG` folder, including file listing and statistics.","permissions":["read-meta","scope-applog-recursive"]},"allow-applog-read":{"identifier":"allow-applog-read","description":"This allows non-recursive read access to the `$APPLOG` folder.","permissions":["read-all","scope-applog"]},"allow-applog-read-recursive":{"identifier":"allow-applog-read-recursive","description":"This allows full recursive read access to the complete `$APPLOG` folder, files and subdirectories.","permissions":["read-all","scope-applog-recursive"]},"allow-applog-write":{"identifier":"allow-applog-write","description":"This allows non-recursive write access to the `$APPLOG` folder.","permissions":["write-all","scope-applog"]},"allow-applog-write-recursive":{"identifier":"allow-applog-write-recursive","description":"This allows full recursive write access to the complete `$APPLOG` folder, files and subdirectories.","permissions":["write-all","scope-applog-recursive"]},"allow-audio-meta":{"identifier":"allow-audio-meta","description":"This allows non-recursive read access to metadata of the `$AUDIO` folder, including file listing and statistics.","permissions":["read-meta","scope-audio-index"]},"allow-audio-meta-recursive":{"identifier":"allow-audio-meta-recursive","description":"This allows full recursive read access to metadata of the `$AUDIO` folder, including file listing and statistics.","permissions":["read-meta","scope-audio-recursive"]},"allow-audio-read":{"identifier":"allow-audio-read","description":"This allows non-recursive read access to the `$AUDIO` folder.","permissions":["read-all","scope-audio"]},"allow-audio-read-recursive":{"identifier":"allow-audio-read-recursive","description":"This allows full recursive read access to the complete `$AUDIO` folder, files and subdirectories.","permissions":["read-all","scope-audio-recursive"]},"allow-audio-write":{"identifier":"allow-audio-write","description":"This allows non-recursive write access to the `$AUDIO` folder.","permissions":["write-all","scope-audio"]},"allow-audio-write-recursive":{"identifier":"allow-audio-write-recursive","description":"This allows full recursive write access to the complete `$AUDIO` folder, files and subdirectories.","permissions":["write-all","scope-audio-recursive"]},"allow-cache-meta":{"identifier":"allow-cache-meta","description":"This allows non-recursive read access to metadata of the `$CACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-cache-index"]},"allow-cache-meta-recursive":{"identifier":"allow-cache-meta-recursive","description":"This allows full recursive read access to metadata of the `$CACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-cache-recursive"]},"allow-cache-read":{"identifier":"allow-cache-read","description":"This allows non-recursive read access to the `$CACHE` folder.","permissions":["read-all","scope-cache"]},"allow-cache-read-recursive":{"identifier":"allow-cache-read-recursive","description":"This allows full recursive read access to the complete `$CACHE` folder, files and subdirectories.","permissions":["read-all","scope-cache-recursive"]},"allow-cache-write":{"identifier":"allow-cache-write","description":"This allows non-recursive write access to the `$CACHE` folder.","permissions":["write-all","scope-cache"]},"allow-cache-write-recursive":{"identifier":"allow-cache-write-recursive","description":"This allows full recursive write access to the complete `$CACHE` folder, files and subdirectories.","permissions":["write-all","scope-cache-recursive"]},"allow-config-meta":{"identifier":"allow-config-meta","description":"This allows non-recursive read access to metadata of the `$CONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-config-index"]},"allow-config-meta-recursive":{"identifier":"allow-config-meta-recursive","description":"This allows full recursive read access to metadata of the `$CONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-config-recursive"]},"allow-config-read":{"identifier":"allow-config-read","description":"This allows non-recursive read access to the `$CONFIG` folder.","permissions":["read-all","scope-config"]},"allow-config-read-recursive":{"identifier":"allow-config-read-recursive","description":"This allows full recursive read access to the complete `$CONFIG` folder, files and subdirectories.","permissions":["read-all","scope-config-recursive"]},"allow-config-write":{"identifier":"allow-config-write","description":"This allows non-recursive write access to the `$CONFIG` folder.","permissions":["write-all","scope-config"]},"allow-config-write-recursive":{"identifier":"allow-config-write-recursive","description":"This allows full recursive write access to the complete `$CONFIG` folder, files and subdirectories.","permissions":["write-all","scope-config-recursive"]},"allow-data-meta":{"identifier":"allow-data-meta","description":"This allows non-recursive read access to metadata of the `$DATA` folder, including file listing and statistics.","permissions":["read-meta","scope-data-index"]},"allow-data-meta-recursive":{"identifier":"allow-data-meta-recursive","description":"This allows full recursive read access to metadata of the `$DATA` folder, including file listing and statistics.","permissions":["read-meta","scope-data-recursive"]},"allow-data-read":{"identifier":"allow-data-read","description":"This allows non-recursive read access to the `$DATA` folder.","permissions":["read-all","scope-data"]},"allow-data-read-recursive":{"identifier":"allow-data-read-recursive","description":"This allows full recursive read access to the complete `$DATA` folder, files and subdirectories.","permissions":["read-all","scope-data-recursive"]},"allow-data-write":{"identifier":"allow-data-write","description":"This allows non-recursive write access to the `$DATA` folder.","permissions":["write-all","scope-data"]},"allow-data-write-recursive":{"identifier":"allow-data-write-recursive","description":"This allows full recursive write access to the complete `$DATA` folder, files and subdirectories.","permissions":["write-all","scope-data-recursive"]},"allow-desktop-meta":{"identifier":"allow-desktop-meta","description":"This allows non-recursive read access to metadata of the `$DESKTOP` folder, including file listing and statistics.","permissions":["read-meta","scope-desktop-index"]},"allow-desktop-meta-recursive":{"identifier":"allow-desktop-meta-recursive","description":"This allows full recursive read access to metadata of the `$DESKTOP` folder, including file listing and statistics.","permissions":["read-meta","scope-desktop-recursive"]},"allow-desktop-read":{"identifier":"allow-desktop-read","description":"This allows non-recursive read access to the `$DESKTOP` folder.","permissions":["read-all","scope-desktop"]},"allow-desktop-read-recursive":{"identifier":"allow-desktop-read-recursive","description":"This allows full recursive read access to the complete `$DESKTOP` folder, files and subdirectories.","permissions":["read-all","scope-desktop-recursive"]},"allow-desktop-write":{"identifier":"allow-desktop-write","description":"This allows non-recursive write access to the `$DESKTOP` folder.","permissions":["write-all","scope-desktop"]},"allow-desktop-write-recursive":{"identifier":"allow-desktop-write-recursive","description":"This allows full recursive write access to the complete `$DESKTOP` folder, files and subdirectories.","permissions":["write-all","scope-desktop-recursive"]},"allow-document-meta":{"identifier":"allow-document-meta","description":"This allows non-recursive read access to metadata of the `$DOCUMENT` folder, including file listing and statistics.","permissions":["read-meta","scope-document-index"]},"allow-document-meta-recursive":{"identifier":"allow-document-meta-recursive","description":"This allows full recursive read access to metadata of the `$DOCUMENT` folder, including file listing and statistics.","permissions":["read-meta","scope-document-recursive"]},"allow-document-read":{"identifier":"allow-document-read","description":"This allows non-recursive read access to the `$DOCUMENT` folder.","permissions":["read-all","scope-document"]},"allow-document-read-recursive":{"identifier":"allow-document-read-recursive","description":"This allows full recursive read access to the complete `$DOCUMENT` folder, files and subdirectories.","permissions":["read-all","scope-document-recursive"]},"allow-document-write":{"identifier":"allow-document-write","description":"This allows non-recursive write access to the `$DOCUMENT` folder.","permissions":["write-all","scope-document"]},"allow-document-write-recursive":{"identifier":"allow-document-write-recursive","description":"This allows full recursive write access to the complete `$DOCUMENT` folder, files and subdirectories.","permissions":["write-all","scope-document-recursive"]},"allow-download-meta":{"identifier":"allow-download-meta","description":"This allows non-recursive read access to metadata of the `$DOWNLOAD` folder, including file listing and statistics.","permissions":["read-meta","scope-download-index"]},"allow-download-meta-recursive":{"identifier":"allow-download-meta-recursive","description":"This allows full recursive read access to metadata of the `$DOWNLOAD` folder, including file listing and statistics.","permissions":["read-meta","scope-download-recursive"]},"allow-download-read":{"identifier":"allow-download-read","description":"This allows non-recursive read access to the `$DOWNLOAD` folder.","permissions":["read-all","scope-download"]},"allow-download-read-recursive":{"identifier":"allow-download-read-recursive","description":"This allows full recursive read access to the complete `$DOWNLOAD` folder, files and subdirectories.","permissions":["read-all","scope-download-recursive"]},"allow-download-write":{"identifier":"allow-download-write","description":"This allows non-recursive write access to the `$DOWNLOAD` folder.","permissions":["write-all","scope-download"]},"allow-download-write-recursive":{"identifier":"allow-download-write-recursive","description":"This allows full recursive write access to the complete `$DOWNLOAD` folder, files and subdirectories.","permissions":["write-all","scope-download-recursive"]},"allow-exe-meta":{"identifier":"allow-exe-meta","description":"This allows non-recursive read access to metadata of the `$EXE` folder, including file listing and statistics.","permissions":["read-meta","scope-exe-index"]},"allow-exe-meta-recursive":{"identifier":"allow-exe-meta-recursive","description":"This allows full recursive read access to metadata of the `$EXE` folder, including file listing and statistics.","permissions":["read-meta","scope-exe-recursive"]},"allow-exe-read":{"identifier":"allow-exe-read","description":"This allows non-recursive read access to the `$EXE` folder.","permissions":["read-all","scope-exe"]},"allow-exe-read-recursive":{"identifier":"allow-exe-read-recursive","description":"This allows full recursive read access to the complete `$EXE` folder, files and subdirectories.","permissions":["read-all","scope-exe-recursive"]},"allow-exe-write":{"identifier":"allow-exe-write","description":"This allows non-recursive write access to the `$EXE` folder.","permissions":["write-all","scope-exe"]},"allow-exe-write-recursive":{"identifier":"allow-exe-write-recursive","description":"This allows full recursive write access to the complete `$EXE` folder, files and subdirectories.","permissions":["write-all","scope-exe-recursive"]},"allow-font-meta":{"identifier":"allow-font-meta","description":"This allows non-recursive read access to metadata of the `$FONT` folder, including file listing and statistics.","permissions":["read-meta","scope-font-index"]},"allow-font-meta-recursive":{"identifier":"allow-font-meta-recursive","description":"This allows full recursive read access to metadata of the `$FONT` folder, including file listing and statistics.","permissions":["read-meta","scope-font-recursive"]},"allow-font-read":{"identifier":"allow-font-read","description":"This allows non-recursive read access to the `$FONT` folder.","permissions":["read-all","scope-font"]},"allow-font-read-recursive":{"identifier":"allow-font-read-recursive","description":"This allows full recursive read access to the complete `$FONT` folder, files and subdirectories.","permissions":["read-all","scope-font-recursive"]},"allow-font-write":{"identifier":"allow-font-write","description":"This allows non-recursive write access to the `$FONT` folder.","permissions":["write-all","scope-font"]},"allow-font-write-recursive":{"identifier":"allow-font-write-recursive","description":"This allows full recursive write access to the complete `$FONT` folder, files and subdirectories.","permissions":["write-all","scope-font-recursive"]},"allow-home-meta":{"identifier":"allow-home-meta","description":"This allows non-recursive read access to metadata of the `$HOME` folder, including file listing and statistics.","permissions":["read-meta","scope-home-index"]},"allow-home-meta-recursive":{"identifier":"allow-home-meta-recursive","description":"This allows full recursive read access to metadata of the `$HOME` folder, including file listing and statistics.","permissions":["read-meta","scope-home-recursive"]},"allow-home-read":{"identifier":"allow-home-read","description":"This allows non-recursive read access to the `$HOME` folder.","permissions":["read-all","scope-home"]},"allow-home-read-recursive":{"identifier":"allow-home-read-recursive","description":"This allows full recursive read access to the complete `$HOME` folder, files and subdirectories.","permissions":["read-all","scope-home-recursive"]},"allow-home-write":{"identifier":"allow-home-write","description":"This allows non-recursive write access to the `$HOME` folder.","permissions":["write-all","scope-home"]},"allow-home-write-recursive":{"identifier":"allow-home-write-recursive","description":"This allows full recursive write access to the complete `$HOME` folder, files and subdirectories.","permissions":["write-all","scope-home-recursive"]},"allow-localdata-meta":{"identifier":"allow-localdata-meta","description":"This allows non-recursive read access to metadata of the `$LOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-localdata-index"]},"allow-localdata-meta-recursive":{"identifier":"allow-localdata-meta-recursive","description":"This allows full recursive read access to metadata of the `$LOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-localdata-recursive"]},"allow-localdata-read":{"identifier":"allow-localdata-read","description":"This allows non-recursive read access to the `$LOCALDATA` folder.","permissions":["read-all","scope-localdata"]},"allow-localdata-read-recursive":{"identifier":"allow-localdata-read-recursive","description":"This allows full recursive read access to the complete `$LOCALDATA` folder, files and subdirectories.","permissions":["read-all","scope-localdata-recursive"]},"allow-localdata-write":{"identifier":"allow-localdata-write","description":"This allows non-recursive write access to the `$LOCALDATA` folder.","permissions":["write-all","scope-localdata"]},"allow-localdata-write-recursive":{"identifier":"allow-localdata-write-recursive","description":"This allows full recursive write access to the complete `$LOCALDATA` folder, files and subdirectories.","permissions":["write-all","scope-localdata-recursive"]},"allow-log-meta":{"identifier":"allow-log-meta","description":"This allows non-recursive read access to metadata of the `$LOG` folder, including file listing and statistics.","permissions":["read-meta","scope-log-index"]},"allow-log-meta-recursive":{"identifier":"allow-log-meta-recursive","description":"This allows full recursive read access to metadata of the `$LOG` folder, including file listing and statistics.","permissions":["read-meta","scope-log-recursive"]},"allow-log-read":{"identifier":"allow-log-read","description":"This allows non-recursive read access to the `$LOG` folder.","permissions":["read-all","scope-log"]},"allow-log-read-recursive":{"identifier":"allow-log-read-recursive","description":"This allows full recursive read access to the complete `$LOG` folder, files and subdirectories.","permissions":["read-all","scope-log-recursive"]},"allow-log-write":{"identifier":"allow-log-write","description":"This allows non-recursive write access to the `$LOG` folder.","permissions":["write-all","scope-log"]},"allow-log-write-recursive":{"identifier":"allow-log-write-recursive","description":"This allows full recursive write access to the complete `$LOG` folder, files and subdirectories.","permissions":["write-all","scope-log-recursive"]},"allow-picture-meta":{"identifier":"allow-picture-meta","description":"This allows non-recursive read access to metadata of the `$PICTURE` folder, including file listing and statistics.","permissions":["read-meta","scope-picture-index"]},"allow-picture-meta-recursive":{"identifier":"allow-picture-meta-recursive","description":"This allows full recursive read access to metadata of the `$PICTURE` folder, including file listing and statistics.","permissions":["read-meta","scope-picture-recursive"]},"allow-picture-read":{"identifier":"allow-picture-read","description":"This allows non-recursive read access to the `$PICTURE` folder.","permissions":["read-all","scope-picture"]},"allow-picture-read-recursive":{"identifier":"allow-picture-read-recursive","description":"This allows full recursive read access to the complete `$PICTURE` folder, files and subdirectories.","permissions":["read-all","scope-picture-recursive"]},"allow-picture-write":{"identifier":"allow-picture-write","description":"This allows non-recursive write access to the `$PICTURE` folder.","permissions":["write-all","scope-picture"]},"allow-picture-write-recursive":{"identifier":"allow-picture-write-recursive","description":"This allows full recursive write access to the complete `$PICTURE` folder, files and subdirectories.","permissions":["write-all","scope-picture-recursive"]},"allow-public-meta":{"identifier":"allow-public-meta","description":"This allows non-recursive read access to metadata of the `$PUBLIC` folder, including file listing and statistics.","permissions":["read-meta","scope-public-index"]},"allow-public-meta-recursive":{"identifier":"allow-public-meta-recursive","description":"This allows full recursive read access to metadata of the `$PUBLIC` folder, including file listing and statistics.","permissions":["read-meta","scope-public-recursive"]},"allow-public-read":{"identifier":"allow-public-read","description":"This allows non-recursive read access to the `$PUBLIC` folder.","permissions":["read-all","scope-public"]},"allow-public-read-recursive":{"identifier":"allow-public-read-recursive","description":"This allows full recursive read access to the complete `$PUBLIC` folder, files and subdirectories.","permissions":["read-all","scope-public-recursive"]},"allow-public-write":{"identifier":"allow-public-write","description":"This allows non-recursive write access to the `$PUBLIC` folder.","permissions":["write-all","scope-public"]},"allow-public-write-recursive":{"identifier":"allow-public-write-recursive","description":"This allows full recursive write access to the complete `$PUBLIC` folder, files and subdirectories.","permissions":["write-all","scope-public-recursive"]},"allow-resource-meta":{"identifier":"allow-resource-meta","description":"This allows non-recursive read access to metadata of the `$RESOURCE` folder, including file listing and statistics.","permissions":["read-meta","scope-resource-index"]},"allow-resource-meta-recursive":{"identifier":"allow-resource-meta-recursive","description":"This allows full recursive read access to metadata of the `$RESOURCE` folder, including file listing and statistics.","permissions":["read-meta","scope-resource-recursive"]},"allow-resource-read":{"identifier":"allow-resource-read","description":"This allows non-recursive read access to the `$RESOURCE` folder.","permissions":["read-all","scope-resource"]},"allow-resource-read-recursive":{"identifier":"allow-resource-read-recursive","description":"This allows full recursive read access to the complete `$RESOURCE` folder, files and subdirectories.","permissions":["read-all","scope-resource-recursive"]},"allow-resource-write":{"identifier":"allow-resource-write","description":"This allows non-recursive write access to the `$RESOURCE` folder.","permissions":["write-all","scope-resource"]},"allow-resource-write-recursive":{"identifier":"allow-resource-write-recursive","description":"This allows full recursive write access to the complete `$RESOURCE` folder, files and subdirectories.","permissions":["write-all","scope-resource-recursive"]},"allow-runtime-meta":{"identifier":"allow-runtime-meta","description":"This allows non-recursive read access to metadata of the `$RUNTIME` folder, including file listing and statistics.","permissions":["read-meta","scope-runtime-index"]},"allow-runtime-meta-recursive":{"identifier":"allow-runtime-meta-recursive","description":"This allows full recursive read access to metadata of the `$RUNTIME` folder, including file listing and statistics.","permissions":["read-meta","scope-runtime-recursive"]},"allow-runtime-read":{"identifier":"allow-runtime-read","description":"This allows non-recursive read access to the `$RUNTIME` folder.","permissions":["read-all","scope-runtime"]},"allow-runtime-read-recursive":{"identifier":"allow-runtime-read-recursive","description":"This allows full recursive read access to the complete `$RUNTIME` folder, files and subdirectories.","permissions":["read-all","scope-runtime-recursive"]},"allow-runtime-write":{"identifier":"allow-runtime-write","description":"This allows non-recursive write access to the `$RUNTIME` folder.","permissions":["write-all","scope-runtime"]},"allow-runtime-write-recursive":{"identifier":"allow-runtime-write-recursive","description":"This allows full recursive write access to the complete `$RUNTIME` folder, files and subdirectories.","permissions":["write-all","scope-runtime-recursive"]},"allow-temp-meta":{"identifier":"allow-temp-meta","description":"This allows non-recursive read access to metadata of the `$TEMP` folder, including file listing and statistics.","permissions":["read-meta","scope-temp-index"]},"allow-temp-meta-recursive":{"identifier":"allow-temp-meta-recursive","description":"This allows full recursive read access to metadata of the `$TEMP` folder, including file listing and statistics.","permissions":["read-meta","scope-temp-recursive"]},"allow-temp-read":{"identifier":"allow-temp-read","description":"This allows non-recursive read access to the `$TEMP` folder.","permissions":["read-all","scope-temp"]},"allow-temp-read-recursive":{"identifier":"allow-temp-read-recursive","description":"This allows full recursive read access to the complete `$TEMP` folder, files and subdirectories.","permissions":["read-all","scope-temp-recursive"]},"allow-temp-write":{"identifier":"allow-temp-write","description":"This allows non-recursive write access to the `$TEMP` folder.","permissions":["write-all","scope-temp"]},"allow-temp-write-recursive":{"identifier":"allow-temp-write-recursive","description":"This allows full recursive write access to the complete `$TEMP` folder, files and subdirectories.","permissions":["write-all","scope-temp-recursive"]},"allow-template-meta":{"identifier":"allow-template-meta","description":"This allows non-recursive read access to metadata of the `$TEMPLATE` folder, including file listing and statistics.","permissions":["read-meta","scope-template-index"]},"allow-template-meta-recursive":{"identifier":"allow-template-meta-recursive","description":"This allows full recursive read access to metadata of the `$TEMPLATE` folder, including file listing and statistics.","permissions":["read-meta","scope-template-recursive"]},"allow-template-read":{"identifier":"allow-template-read","description":"This allows non-recursive read access to the `$TEMPLATE` folder.","permissions":["read-all","scope-template"]},"allow-template-read-recursive":{"identifier":"allow-template-read-recursive","description":"This allows full recursive read access to the complete `$TEMPLATE` folder, files and subdirectories.","permissions":["read-all","scope-template-recursive"]},"allow-template-write":{"identifier":"allow-template-write","description":"This allows non-recursive write access to the `$TEMPLATE` folder.","permissions":["write-all","scope-template"]},"allow-template-write-recursive":{"identifier":"allow-template-write-recursive","description":"This allows full recursive write access to the complete `$TEMPLATE` folder, files and subdirectories.","permissions":["write-all","scope-template-recursive"]},"allow-video-meta":{"identifier":"allow-video-meta","description":"This allows non-recursive read access to metadata of the `$VIDEO` folder, including file listing and statistics.","permissions":["read-meta","scope-video-index"]},"allow-video-meta-recursive":{"identifier":"allow-video-meta-recursive","description":"This allows full recursive read access to metadata of the `$VIDEO` folder, including file listing and statistics.","permissions":["read-meta","scope-video-recursive"]},"allow-video-read":{"identifier":"allow-video-read","description":"This allows non-recursive read access to the `$VIDEO` folder.","permissions":["read-all","scope-video"]},"allow-video-read-recursive":{"identifier":"allow-video-read-recursive","description":"This allows full recursive read access to the complete `$VIDEO` folder, files and subdirectories.","permissions":["read-all","scope-video-recursive"]},"allow-video-write":{"identifier":"allow-video-write","description":"This allows non-recursive write access to the `$VIDEO` folder.","permissions":["write-all","scope-video"]},"allow-video-write-recursive":{"identifier":"allow-video-write-recursive","description":"This allows full recursive write access to the complete `$VIDEO` folder, files and subdirectories.","permissions":["write-all","scope-video-recursive"]},"deny-default":{"identifier":"deny-default","description":"This denies access to dangerous Tauri relevant files and folders by default.","permissions":["deny-webview-data-linux","deny-webview-data-windows"]}},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"description":"A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},{"properties":{"path":{"description":"A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"description":"FS scope entry.","title":"FsScopeEntry"}},"log":{"default_permission":{"identifier":"default","description":"Allows the log command","permissions":["allow-log"]},"permissions":{"allow-log":{"identifier":"allow-log","description":"Enables the log command without any pre-configured scope.","commands":{"allow":["log"],"deny":[]}},"deny-log":{"identifier":"deny-log","description":"Denies the log command without any pre-configured scope.","commands":{"allow":[],"deny":["log"]}}},"permission_sets":{},"global_scope_schema":null},"opener":{"default_permission":{"identifier":"default","description":"This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer","permissions":["allow-open-url","allow-reveal-item-in-dir","allow-default-urls"]},"permissions":{"allow-default-urls":{"identifier":"allow-default-urls","description":"This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"url":"mailto:*"},{"url":"tel:*"},{"url":"http://*"},{"url":"https://*"}]}},"allow-open-path":{"identifier":"allow-open-path","description":"Enables the open_path command without any pre-configured scope.","commands":{"allow":["open_path"],"deny":[]}},"allow-open-url":{"identifier":"allow-open-url","description":"Enables the open_url command without any pre-configured scope.","commands":{"allow":["open_url"],"deny":[]}},"allow-reveal-item-in-dir":{"identifier":"allow-reveal-item-in-dir","description":"Enables the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":["reveal_item_in_dir"],"deny":[]}},"deny-open-path":{"identifier":"deny-open-path","description":"Denies the open_path command without any pre-configured scope.","commands":{"allow":[],"deny":["open_path"]}},"deny-open-url":{"identifier":"deny-open-url","description":"Denies the open_url command without any pre-configured scope.","commands":{"allow":[],"deny":["open_url"]}},"deny-reveal-item-in-dir":{"identifier":"deny-reveal-item-in-dir","description":"Denies the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["reveal_item_in_dir"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this url with, for example: firefox."},"url":{"description":"A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.amrom.workers.dev/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"","type":"string"}},"required":["url"],"type":"object"},{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this path with, for example: xdg-open."},"path":{"description":"A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"definitions":{"Application":{"anyOf":[{"description":"Open in default application.","type":"null"},{"description":"If true, allow open with any application.","type":"boolean"},{"description":"Allow specific application to open with.","type":"string"}],"description":"Opener scope application."}},"description":"Opener scope entry.","title":"OpenerScopeEntry"}},"os":{"default_permission":{"identifier":"default","description":"This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n","permissions":["allow-arch","allow-exe-extension","allow-family","allow-locale","allow-os-type","allow-platform","allow-version"]},"permissions":{"allow-arch":{"identifier":"allow-arch","description":"Enables the arch command without any pre-configured scope.","commands":{"allow":["arch"],"deny":[]}},"allow-exe-extension":{"identifier":"allow-exe-extension","description":"Enables the exe_extension command without any pre-configured scope.","commands":{"allow":["exe_extension"],"deny":[]}},"allow-family":{"identifier":"allow-family","description":"Enables the family command without any pre-configured scope.","commands":{"allow":["family"],"deny":[]}},"allow-hostname":{"identifier":"allow-hostname","description":"Enables the hostname command without any pre-configured scope.","commands":{"allow":["hostname"],"deny":[]}},"allow-locale":{"identifier":"allow-locale","description":"Enables the locale command without any pre-configured scope.","commands":{"allow":["locale"],"deny":[]}},"allow-os-type":{"identifier":"allow-os-type","description":"Enables the os_type command without any pre-configured scope.","commands":{"allow":["os_type"],"deny":[]}},"allow-platform":{"identifier":"allow-platform","description":"Enables the platform command without any pre-configured scope.","commands":{"allow":["platform"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-arch":{"identifier":"deny-arch","description":"Denies the arch command without any pre-configured scope.","commands":{"allow":[],"deny":["arch"]}},"deny-exe-extension":{"identifier":"deny-exe-extension","description":"Denies the exe_extension command without any pre-configured scope.","commands":{"allow":[],"deny":["exe_extension"]}},"deny-family":{"identifier":"deny-family","description":"Denies the family command without any pre-configured scope.","commands":{"allow":[],"deny":["family"]}},"deny-hostname":{"identifier":"deny-hostname","description":"Denies the hostname command without any pre-configured scope.","commands":{"allow":[],"deny":["hostname"]}},"deny-locale":{"identifier":"deny-locale","description":"Denies the locale command without any pre-configured scope.","commands":{"allow":[],"deny":["locale"]}},"deny-os-type":{"identifier":"deny-os-type","description":"Denies the os_type command without any pre-configured scope.","commands":{"allow":[],"deny":["os_type"]}},"deny-platform":{"identifier":"deny-platform","description":"Denies the platform command without any pre-configured scope.","commands":{"allow":[],"deny":["platform"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"}},"required":["cmd","name"],"type":"object"},{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["name","sidecar"],"type":"object"}],"definitions":{"ShellScopeEntryAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"raw":{"default":false,"description":"Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.","type":"boolean"},"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellScopeEntryAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellScopeEntryAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"Shell scope entry.","title":"ShellScopeEntry"}},"updater":{"default_permission":{"identifier":"default","description":"This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n","permissions":["allow-check","allow-download","allow-install","allow-download-and-install"]},"permissions":{"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"allow-download":{"identifier":"allow-download","description":"Enables the download command without any pre-configured scope.","commands":{"allow":["download"],"deny":[]}},"allow-download-and-install":{"identifier":"allow-download-and-install","description":"Enables the download_and_install command without any pre-configured scope.","commands":{"allow":["download_and_install"],"deny":[]}},"allow-install":{"identifier":"allow-install","description":"Enables the install command without any pre-configured scope.","commands":{"allow":["install"],"deny":[]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}},"deny-download":{"identifier":"deny-download","description":"Denies the download command without any pre-configured scope.","commands":{"allow":[],"deny":["download"]}},"deny-download-and-install":{"identifier":"deny-download-and-install","description":"Denies the download_and_install command without any pre-configured scope.","commands":{"allow":[],"deny":["download_and_install"]}},"deny-install":{"identifier":"deny-install","description":"Denies the install command without any pre-configured scope.","commands":{"allow":[],"deny":["install"]}}},"permission_sets":{},"global_scope_schema":null},"window-state":{"default_permission":{"identifier":"default","description":"This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n","permissions":["allow-filename","allow-restore-state","allow-save-window-state"]},"permissions":{"allow-filename":{"identifier":"allow-filename","description":"Enables the filename command without any pre-configured scope.","commands":{"allow":["filename"],"deny":[]}},"allow-restore-state":{"identifier":"allow-restore-state","description":"Enables the restore_state command without any pre-configured scope.","commands":{"allow":["restore_state"],"deny":[]}},"allow-save-window-state":{"identifier":"allow-save-window-state","description":"Enables the save_window_state command without any pre-configured scope.","commands":{"allow":["save_window_state"],"deny":[]}},"deny-filename":{"identifier":"deny-filename","description":"Denies the filename command without any pre-configured scope.","commands":{"allow":[],"deny":["filename"]}},"deny-restore-state":{"identifier":"deny-restore-state","description":"Denies the restore_state command without any pre-configured scope.","commands":{"allow":[],"deny":["restore_state"]}},"deny-save-window-state":{"identifier":"deny-save-window-state","description":"Denies the save_window_state command without any pre-configured scope.","commands":{"allow":[],"deny":["save_window_state"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-git":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-add","allow-branch","allow-checkout","allow-commit","allow-delete-branch","allow-fetch-all","allow-initialize","allow-log","allow-merge-branch","allow-pull","allow-push","allow-status","allow-unstage"]},"permissions":{"allow-add":{"identifier":"allow-add","description":"Enables the add command without any pre-configured scope.","commands":{"allow":["add"],"deny":[]}},"allow-branch":{"identifier":"allow-branch","description":"Enables the branch command without any pre-configured scope.","commands":{"allow":["branch"],"deny":[]}},"allow-checkout":{"identifier":"allow-checkout","description":"Enables the checkout command without any pre-configured scope.","commands":{"allow":["checkout"],"deny":[]}},"allow-checkout-remote":{"identifier":"allow-checkout-remote","description":"Enables the checkout_remote command without any pre-configured scope.","commands":{"allow":["checkout_remote"],"deny":[]}},"allow-commit":{"identifier":"allow-commit","description":"Enables the commit command without any pre-configured scope.","commands":{"allow":["commit"],"deny":[]}},"allow-delete-branch":{"identifier":"allow-delete-branch","description":"Enables the delete_branch command without any pre-configured scope.","commands":{"allow":["delete_branch"],"deny":[]}},"allow-fetch-all":{"identifier":"allow-fetch-all","description":"Enables the fetch_all command without any pre-configured scope.","commands":{"allow":["fetch_all"],"deny":[]}},"allow-initialize":{"identifier":"allow-initialize","description":"Enables the initialize command without any pre-configured scope.","commands":{"allow":["initialize"],"deny":[]}},"allow-log":{"identifier":"allow-log","description":"Enables the log command without any pre-configured scope.","commands":{"allow":["log"],"deny":[]}},"allow-merge-branch":{"identifier":"allow-merge-branch","description":"Enables the merge_branch command without any pre-configured scope.","commands":{"allow":["merge_branch"],"deny":[]}},"allow-pull":{"identifier":"allow-pull","description":"Enables the pull command without any pre-configured scope.","commands":{"allow":["pull"],"deny":[]}},"allow-push":{"identifier":"allow-push","description":"Enables the push command without any pre-configured scope.","commands":{"allow":["push"],"deny":[]}},"allow-status":{"identifier":"allow-status","description":"Enables the status command without any pre-configured scope.","commands":{"allow":["status"],"deny":[]}},"allow-unstage":{"identifier":"allow-unstage","description":"Enables the unstage command without any pre-configured scope.","commands":{"allow":["unstage"],"deny":[]}},"deny-add":{"identifier":"deny-add","description":"Denies the add command without any pre-configured scope.","commands":{"allow":[],"deny":["add"]}},"deny-branch":{"identifier":"deny-branch","description":"Denies the branch command without any pre-configured scope.","commands":{"allow":[],"deny":["branch"]}},"deny-checkout":{"identifier":"deny-checkout","description":"Denies the checkout command without any pre-configured scope.","commands":{"allow":[],"deny":["checkout"]}},"deny-checkout-remote":{"identifier":"deny-checkout-remote","description":"Denies the checkout_remote command without any pre-configured scope.","commands":{"allow":[],"deny":["checkout_remote"]}},"deny-commit":{"identifier":"deny-commit","description":"Denies the commit command without any pre-configured scope.","commands":{"allow":[],"deny":["commit"]}},"deny-delete-branch":{"identifier":"deny-delete-branch","description":"Denies the delete_branch command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_branch"]}},"deny-fetch-all":{"identifier":"deny-fetch-all","description":"Denies the fetch_all command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_all"]}},"deny-initialize":{"identifier":"deny-initialize","description":"Denies the initialize command without any pre-configured scope.","commands":{"allow":[],"deny":["initialize"]}},"deny-log":{"identifier":"deny-log","description":"Denies the log command without any pre-configured scope.","commands":{"allow":[],"deny":["log"]}},"deny-merge-branch":{"identifier":"deny-merge-branch","description":"Denies the merge_branch command without any pre-configured scope.","commands":{"allow":[],"deny":["merge_branch"]}},"deny-pull":{"identifier":"deny-pull","description":"Denies the pull command without any pre-configured scope.","commands":{"allow":[],"deny":["pull"]}},"deny-push":{"identifier":"deny-push","description":"Denies the push command without any pre-configured scope.","commands":{"allow":[],"deny":["push"]}},"deny-status":{"identifier":"deny-status","description":"Denies the status command without any pre-configured scope.","commands":{"allow":[],"deny":["status"]}},"deny-unstage":{"identifier":"deny-unstage","description":"Denies the unstage command without any pre-configured scope.","commands":{"allow":[],"deny":["unstage"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-license":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-check","allow-activate"]},"permissions":{"allow-activate":{"identifier":"allow-activate","description":"Enables the activate command without any pre-configured scope.","commands":{"allow":["activate"],"deny":[]}},"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"deny-activate":{"identifier":"deny-activate","description":"Denies the activate command without any pre-configured scope.","commands":{"allow":[],"deny":["activate"]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-sync":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-calculate","allow-calculate-fs","allow-apply","allow-watch"]},"permissions":{"allow-apply":{"identifier":"allow-apply","description":"Enables the apply command without any pre-configured scope.","commands":{"allow":["apply"],"deny":[]}},"allow-calculate":{"identifier":"allow-calculate","description":"Enables the calculate command without any pre-configured scope.","commands":{"allow":["calculate"],"deny":[]}},"allow-calculate-fs":{"identifier":"allow-calculate-fs","description":"Enables the calculate_fs command without any pre-configured scope.","commands":{"allow":["calculate_fs"],"deny":[]}},"allow-watch":{"identifier":"allow-watch","description":"Enables the watch command without any pre-configured scope.","commands":{"allow":["watch"],"deny":[]}},"deny-apply":{"identifier":"deny-apply","description":"Denies the apply command without any pre-configured scope.","commands":{"allow":[],"deny":["apply"]}},"deny-calculate":{"identifier":"deny-calculate","description":"Denies the calculate command without any pre-configured scope.","commands":{"allow":[],"deny":["calculate"]}},"deny-calculate-fs":{"identifier":"deny-calculate-fs","description":"Denies the calculate_fs command without any pre-configured scope.","commands":{"allow":[],"deny":["calculate_fs"]}},"deny-watch":{"identifier":"deny-watch","description":"Denies the watch command without any pre-configured scope.","commands":{"allow":[],"deny":["watch"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-ws":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-close","allow-connect","allow-delete-connection","allow-delete-connections","allow-delete-request","allow-duplicate-request","allow-list-connections","allow-list-events","allow-list-requests","allow-send","allow-upsert-request"]},"permissions":{"allow-cancel":{"identifier":"allow-cancel","description":"Enables the cancel command without any pre-configured scope.","commands":{"allow":["cancel"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-connect":{"identifier":"allow-connect","description":"Enables the connect command without any pre-configured scope.","commands":{"allow":["connect"],"deny":[]}},"allow-delete-connection":{"identifier":"allow-delete-connection","description":"Enables the delete_connection command without any pre-configured scope.","commands":{"allow":["delete_connection"],"deny":[]}},"allow-delete-connections":{"identifier":"allow-delete-connections","description":"Enables the delete_connections command without any pre-configured scope.","commands":{"allow":["delete_connections"],"deny":[]}},"allow-delete-request":{"identifier":"allow-delete-request","description":"Enables the delete_request command without any pre-configured scope.","commands":{"allow":["delete_request"],"deny":[]}},"allow-duplicate-request":{"identifier":"allow-duplicate-request","description":"Enables the duplicate_request command without any pre-configured scope.","commands":{"allow":["duplicate_request"],"deny":[]}},"allow-list-connections":{"identifier":"allow-list-connections","description":"Enables the list_connections command without any pre-configured scope.","commands":{"allow":["list_connections"],"deny":[]}},"allow-list-events":{"identifier":"allow-list-events","description":"Enables the list_events command without any pre-configured scope.","commands":{"allow":["list_events"],"deny":[]}},"allow-list-requests":{"identifier":"allow-list-requests","description":"Enables the list_requests command without any pre-configured scope.","commands":{"allow":["list_requests"],"deny":[]}},"allow-list-websocket-connections":{"identifier":"allow-list-websocket-connections","description":"Enables the list_websocket_connections command without any pre-configured scope.","commands":{"allow":["list_websocket_connections"],"deny":[]}},"allow-list-websocket-requests":{"identifier":"allow-list-websocket-requests","description":"Enables the list_websocket_requests command without any pre-configured scope.","commands":{"allow":["list_websocket_requests"],"deny":[]}},"allow-send":{"identifier":"allow-send","description":"Enables the send command without any pre-configured scope.","commands":{"allow":["send"],"deny":[]}},"allow-upsert-request":{"identifier":"allow-upsert-request","description":"Enables the upsert_request command without any pre-configured scope.","commands":{"allow":["upsert_request"],"deny":[]}},"allow-upsert-websocket-request":{"identifier":"allow-upsert-websocket-request","description":"Enables the upsert_websocket_request command without any pre-configured scope.","commands":{"allow":["upsert_websocket_request"],"deny":[]}},"deny-cancel":{"identifier":"deny-cancel","description":"Denies the cancel command without any pre-configured scope.","commands":{"allow":[],"deny":["cancel"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-connect":{"identifier":"deny-connect","description":"Denies the connect command without any pre-configured scope.","commands":{"allow":[],"deny":["connect"]}},"deny-delete-connection":{"identifier":"deny-delete-connection","description":"Denies the delete_connection command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_connection"]}},"deny-delete-connections":{"identifier":"deny-delete-connections","description":"Denies the delete_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_connections"]}},"deny-delete-request":{"identifier":"deny-delete-request","description":"Denies the delete_request command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_request"]}},"deny-duplicate-request":{"identifier":"deny-duplicate-request","description":"Denies the duplicate_request command without any pre-configured scope.","commands":{"allow":[],"deny":["duplicate_request"]}},"deny-list-connections":{"identifier":"deny-list-connections","description":"Denies the list_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["list_connections"]}},"deny-list-events":{"identifier":"deny-list-events","description":"Denies the list_events command without any pre-configured scope.","commands":{"allow":[],"deny":["list_events"]}},"deny-list-requests":{"identifier":"deny-list-requests","description":"Denies the list_requests command without any pre-configured scope.","commands":{"allow":[],"deny":["list_requests"]}},"deny-list-websocket-connections":{"identifier":"deny-list-websocket-connections","description":"Denies the list_websocket_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["list_websocket_connections"]}},"deny-list-websocket-requests":{"identifier":"deny-list-websocket-requests","description":"Denies the list_websocket_requests command without any pre-configured scope.","commands":{"allow":[],"deny":["list_websocket_requests"]}},"deny-send":{"identifier":"deny-send","description":"Denies the send command without any pre-configured scope.","commands":{"allow":[],"deny":["send"]}},"deny-upsert-request":{"identifier":"deny-upsert-request","description":"Denies the upsert_request command without any pre-configured scope.","commands":{"allow":[],"deny":["upsert_request"]}},"deny-upsert-websocket-request":{"identifier":"deny-upsert-websocket-request","description":"Denies the upsert_websocket_request command without any pre-configured scope.","commands":{"allow":[],"deny":["upsert_websocket_request"]}}},"permission_sets":{},"global_scope_schema":null}} \ No newline at end of file +{"clipboard-manager":{"default_permission":{"identifier":"default","description":"No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n","permissions":[]},"permissions":{"allow-clear":{"identifier":"allow-clear","description":"Enables the clear command without any pre-configured scope.","commands":{"allow":["clear"],"deny":[]}},"allow-read-image":{"identifier":"allow-read-image","description":"Enables the read_image command without any pre-configured scope.","commands":{"allow":["read_image"],"deny":[]}},"allow-read-text":{"identifier":"allow-read-text","description":"Enables the read_text command without any pre-configured scope.","commands":{"allow":["read_text"],"deny":[]}},"allow-write-html":{"identifier":"allow-write-html","description":"Enables the write_html command without any pre-configured scope.","commands":{"allow":["write_html"],"deny":[]}},"allow-write-image":{"identifier":"allow-write-image","description":"Enables the write_image command without any pre-configured scope.","commands":{"allow":["write_image"],"deny":[]}},"allow-write-text":{"identifier":"allow-write-text","description":"Enables the write_text command without any pre-configured scope.","commands":{"allow":["write_text"],"deny":[]}},"deny-clear":{"identifier":"deny-clear","description":"Denies the clear command without any pre-configured scope.","commands":{"allow":[],"deny":["clear"]}},"deny-read-image":{"identifier":"deny-read-image","description":"Denies the read_image command without any pre-configured scope.","commands":{"allow":[],"deny":["read_image"]}},"deny-read-text":{"identifier":"deny-read-text","description":"Denies the read_text command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text"]}},"deny-write-html":{"identifier":"deny-write-html","description":"Denies the write_html command without any pre-configured scope.","commands":{"allow":[],"deny":["write_html"]}},"deny-write-image":{"identifier":"deny-write-image","description":"Denies the write_image command without any pre-configured scope.","commands":{"allow":[],"deny":["write_image"]}},"deny-write-text":{"identifier":"deny-write-text","description":"Denies the write_text command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text"]}}},"permission_sets":{},"global_scope_schema":null},"core":{"default_permission":{"identifier":"default","description":"Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-ask","allow-confirm","allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope.","commands":{"allow":["ask"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope.","commands":{"allow":["confirm"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope.","commands":{"allow":[],"deny":["ask"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope.","commands":{"allow":[],"deny":["confirm"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"fs":{"default_permission":{"identifier":"default","description":"This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n","permissions":["create-app-specific-dirs","read-app-specific-dirs-recursive","deny-default"]},"permissions":{"allow-copy-file":{"identifier":"allow-copy-file","description":"Enables the copy_file command without any pre-configured scope.","commands":{"allow":["copy_file"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-exists":{"identifier":"allow-exists","description":"Enables the exists command without any pre-configured scope.","commands":{"allow":["exists"],"deny":[]}},"allow-fstat":{"identifier":"allow-fstat","description":"Enables the fstat command without any pre-configured scope.","commands":{"allow":["fstat"],"deny":[]}},"allow-ftruncate":{"identifier":"allow-ftruncate","description":"Enables the ftruncate command without any pre-configured scope.","commands":{"allow":["ftruncate"],"deny":[]}},"allow-lstat":{"identifier":"allow-lstat","description":"Enables the lstat command without any pre-configured scope.","commands":{"allow":["lstat"],"deny":[]}},"allow-mkdir":{"identifier":"allow-mkdir","description":"Enables the mkdir command without any pre-configured scope.","commands":{"allow":["mkdir"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-read":{"identifier":"allow-read","description":"Enables the read command without any pre-configured scope.","commands":{"allow":["read"],"deny":[]}},"allow-read-dir":{"identifier":"allow-read-dir","description":"Enables the read_dir command without any pre-configured scope.","commands":{"allow":["read_dir"],"deny":[]}},"allow-read-file":{"identifier":"allow-read-file","description":"Enables the read_file command without any pre-configured scope.","commands":{"allow":["read_file"],"deny":[]}},"allow-read-text-file":{"identifier":"allow-read-text-file","description":"Enables the read_text_file command without any pre-configured scope.","commands":{"allow":["read_text_file"],"deny":[]}},"allow-read-text-file-lines":{"identifier":"allow-read-text-file-lines","description":"Enables the read_text_file_lines command without any pre-configured scope.","commands":{"allow":["read_text_file_lines","read_text_file_lines_next"],"deny":[]}},"allow-read-text-file-lines-next":{"identifier":"allow-read-text-file-lines-next","description":"Enables the read_text_file_lines_next command without any pre-configured scope.","commands":{"allow":["read_text_file_lines_next"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-rename":{"identifier":"allow-rename","description":"Enables the rename command without any pre-configured scope.","commands":{"allow":["rename"],"deny":[]}},"allow-seek":{"identifier":"allow-seek","description":"Enables the seek command without any pre-configured scope.","commands":{"allow":["seek"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"allow-stat":{"identifier":"allow-stat","description":"Enables the stat command without any pre-configured scope.","commands":{"allow":["stat"],"deny":[]}},"allow-truncate":{"identifier":"allow-truncate","description":"Enables the truncate command without any pre-configured scope.","commands":{"allow":["truncate"],"deny":[]}},"allow-unwatch":{"identifier":"allow-unwatch","description":"Enables the unwatch command without any pre-configured scope.","commands":{"allow":["unwatch"],"deny":[]}},"allow-watch":{"identifier":"allow-watch","description":"Enables the watch command without any pre-configured scope.","commands":{"allow":["watch"],"deny":[]}},"allow-write":{"identifier":"allow-write","description":"Enables the write command without any pre-configured scope.","commands":{"allow":["write"],"deny":[]}},"allow-write-file":{"identifier":"allow-write-file","description":"Enables the write_file command without any pre-configured scope.","commands":{"allow":["write_file","open","write"],"deny":[]}},"allow-write-text-file":{"identifier":"allow-write-text-file","description":"Enables the write_text_file command without any pre-configured scope.","commands":{"allow":["write_text_file"],"deny":[]}},"create-app-specific-dirs":{"identifier":"create-app-specific-dirs","description":"This permissions allows to create the application specific directories.\n","commands":{"allow":["mkdir","scope-app-index"],"deny":[]}},"deny-copy-file":{"identifier":"deny-copy-file","description":"Denies the copy_file command without any pre-configured scope.","commands":{"allow":[],"deny":["copy_file"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-exists":{"identifier":"deny-exists","description":"Denies the exists command without any pre-configured scope.","commands":{"allow":[],"deny":["exists"]}},"deny-fstat":{"identifier":"deny-fstat","description":"Denies the fstat command without any pre-configured scope.","commands":{"allow":[],"deny":["fstat"]}},"deny-ftruncate":{"identifier":"deny-ftruncate","description":"Denies the ftruncate command without any pre-configured scope.","commands":{"allow":[],"deny":["ftruncate"]}},"deny-lstat":{"identifier":"deny-lstat","description":"Denies the lstat command without any pre-configured scope.","commands":{"allow":[],"deny":["lstat"]}},"deny-mkdir":{"identifier":"deny-mkdir","description":"Denies the mkdir command without any pre-configured scope.","commands":{"allow":[],"deny":["mkdir"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-read":{"identifier":"deny-read","description":"Denies the read command without any pre-configured scope.","commands":{"allow":[],"deny":["read"]}},"deny-read-dir":{"identifier":"deny-read-dir","description":"Denies the read_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["read_dir"]}},"deny-read-file":{"identifier":"deny-read-file","description":"Denies the read_file command without any pre-configured scope.","commands":{"allow":[],"deny":["read_file"]}},"deny-read-text-file":{"identifier":"deny-read-text-file","description":"Denies the read_text_file command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file"]}},"deny-read-text-file-lines":{"identifier":"deny-read-text-file-lines","description":"Denies the read_text_file_lines command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file_lines"]}},"deny-read-text-file-lines-next":{"identifier":"deny-read-text-file-lines-next","description":"Denies the read_text_file_lines_next command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file_lines_next"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-rename":{"identifier":"deny-rename","description":"Denies the rename command without any pre-configured scope.","commands":{"allow":[],"deny":["rename"]}},"deny-seek":{"identifier":"deny-seek","description":"Denies the seek command without any pre-configured scope.","commands":{"allow":[],"deny":["seek"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}},"deny-stat":{"identifier":"deny-stat","description":"Denies the stat command without any pre-configured scope.","commands":{"allow":[],"deny":["stat"]}},"deny-truncate":{"identifier":"deny-truncate","description":"Denies the truncate command without any pre-configured scope.","commands":{"allow":[],"deny":["truncate"]}},"deny-unwatch":{"identifier":"deny-unwatch","description":"Denies the unwatch command without any pre-configured scope.","commands":{"allow":[],"deny":["unwatch"]}},"deny-watch":{"identifier":"deny-watch","description":"Denies the watch command without any pre-configured scope.","commands":{"allow":[],"deny":["watch"]}},"deny-webview-data-linux":{"identifier":"deny-webview-data-linux","description":"This denies read access to the\n`$APPLOCALDATA` folder on linux as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.","commands":{"allow":[],"deny":[]}},"deny-webview-data-windows":{"identifier":"deny-webview-data-windows","description":"This denies read access to the\n`$APPLOCALDATA/EBWebView` folder on windows as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.","commands":{"allow":[],"deny":[]}},"deny-write":{"identifier":"deny-write","description":"Denies the write command without any pre-configured scope.","commands":{"allow":[],"deny":["write"]}},"deny-write-file":{"identifier":"deny-write-file","description":"Denies the write_file command without any pre-configured scope.","commands":{"allow":[],"deny":["write_file"]}},"deny-write-text-file":{"identifier":"deny-write-text-file","description":"Denies the write_text_file command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text_file"]}},"read-all":{"identifier":"read-all","description":"This enables all read related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","read_file","read","open","read_text_file","read_text_file_lines","read_text_file_lines_next","seek","stat","lstat","fstat","exists","watch","unwatch"],"deny":[]}},"read-app-specific-dirs-recursive":{"identifier":"read-app-specific-dirs-recursive","description":"This permission allows recursive read functionality on the application\nspecific base directories. \n","commands":{"allow":["read_dir","read_file","read_text_file","read_text_file_lines","read_text_file_lines_next","exists","scope-app-recursive"],"deny":[]}},"read-dirs":{"identifier":"read-dirs","description":"This enables directory read and file metadata related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","stat","lstat","fstat","exists"],"deny":[]}},"read-files":{"identifier":"read-files","description":"This enables file read related commands without any pre-configured accessible paths.","commands":{"allow":["read_file","read","open","read_text_file","read_text_file_lines","read_text_file_lines_next","seek","stat","lstat","fstat","exists"],"deny":[]}},"read-meta":{"identifier":"read-meta","description":"This enables all index or metadata related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","stat","lstat","fstat","exists","size"],"deny":[]}},"scope":{"identifier":"scope","description":"An empty permission you can use to modify the global scope.","commands":{"allow":[],"deny":[]}},"scope-app":{"identifier":"scope-app","description":"This scope permits access to all files and list content of top level directories in the application folders.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/*"},{"path":"$APPDATA"},{"path":"$APPDATA/*"},{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/*"},{"path":"$APPCACHE"},{"path":"$APPCACHE/*"},{"path":"$APPLOG"},{"path":"$APPLOG/*"}]}},"scope-app-index":{"identifier":"scope-app-index","description":"This scope permits to list all files and folders in the application directories.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPDATA"},{"path":"$APPLOCALDATA"},{"path":"$APPCACHE"},{"path":"$APPLOG"}]}},"scope-app-recursive":{"identifier":"scope-app-recursive","description":"This scope permits recursive access to the complete application folders, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/**"},{"path":"$APPDATA"},{"path":"$APPDATA/**"},{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/**"},{"path":"$APPCACHE"},{"path":"$APPCACHE/**"},{"path":"$APPLOG"},{"path":"$APPLOG/**"}]}},"scope-appcache":{"identifier":"scope-appcache","description":"This scope permits access to all files and list content of top level directories in the `$APPCACHE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"},{"path":"$APPCACHE/*"}]}},"scope-appcache-index":{"identifier":"scope-appcache-index","description":"This scope permits to list all files and folders in the `$APPCACHE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"}]}},"scope-appcache-recursive":{"identifier":"scope-appcache-recursive","description":"This scope permits recursive access to the complete `$APPCACHE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"},{"path":"$APPCACHE/**"}]}},"scope-appconfig":{"identifier":"scope-appconfig","description":"This scope permits access to all files and list content of top level directories in the `$APPCONFIG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/*"}]}},"scope-appconfig-index":{"identifier":"scope-appconfig-index","description":"This scope permits to list all files and folders in the `$APPCONFIG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"}]}},"scope-appconfig-recursive":{"identifier":"scope-appconfig-recursive","description":"This scope permits recursive access to the complete `$APPCONFIG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/**"}]}},"scope-appdata":{"identifier":"scope-appdata","description":"This scope permits access to all files and list content of top level directories in the `$APPDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"},{"path":"$APPDATA/*"}]}},"scope-appdata-index":{"identifier":"scope-appdata-index","description":"This scope permits to list all files and folders in the `$APPDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"}]}},"scope-appdata-recursive":{"identifier":"scope-appdata-recursive","description":"This scope permits recursive access to the complete `$APPDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]}},"scope-applocaldata":{"identifier":"scope-applocaldata","description":"This scope permits access to all files and list content of top level directories in the `$APPLOCALDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/*"}]}},"scope-applocaldata-index":{"identifier":"scope-applocaldata-index","description":"This scope permits to list all files and folders in the `$APPLOCALDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"}]}},"scope-applocaldata-recursive":{"identifier":"scope-applocaldata-recursive","description":"This scope permits recursive access to the complete `$APPLOCALDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/**"}]}},"scope-applog":{"identifier":"scope-applog","description":"This scope permits access to all files and list content of top level directories in the `$APPLOG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"},{"path":"$APPLOG/*"}]}},"scope-applog-index":{"identifier":"scope-applog-index","description":"This scope permits to list all files and folders in the `$APPLOG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"}]}},"scope-applog-recursive":{"identifier":"scope-applog-recursive","description":"This scope permits recursive access to the complete `$APPLOG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"},{"path":"$APPLOG/**"}]}},"scope-audio":{"identifier":"scope-audio","description":"This scope permits access to all files and list content of top level directories in the `$AUDIO` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"},{"path":"$AUDIO/*"}]}},"scope-audio-index":{"identifier":"scope-audio-index","description":"This scope permits to list all files and folders in the `$AUDIO`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"}]}},"scope-audio-recursive":{"identifier":"scope-audio-recursive","description":"This scope permits recursive access to the complete `$AUDIO` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"},{"path":"$AUDIO/**"}]}},"scope-cache":{"identifier":"scope-cache","description":"This scope permits access to all files and list content of top level directories in the `$CACHE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"},{"path":"$CACHE/*"}]}},"scope-cache-index":{"identifier":"scope-cache-index","description":"This scope permits to list all files and folders in the `$CACHE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"}]}},"scope-cache-recursive":{"identifier":"scope-cache-recursive","description":"This scope permits recursive access to the complete `$CACHE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"},{"path":"$CACHE/**"}]}},"scope-config":{"identifier":"scope-config","description":"This scope permits access to all files and list content of top level directories in the `$CONFIG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"},{"path":"$CONFIG/*"}]}},"scope-config-index":{"identifier":"scope-config-index","description":"This scope permits to list all files and folders in the `$CONFIG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"}]}},"scope-config-recursive":{"identifier":"scope-config-recursive","description":"This scope permits recursive access to the complete `$CONFIG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"},{"path":"$CONFIG/**"}]}},"scope-data":{"identifier":"scope-data","description":"This scope permits access to all files and list content of top level directories in the `$DATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"},{"path":"$DATA/*"}]}},"scope-data-index":{"identifier":"scope-data-index","description":"This scope permits to list all files and folders in the `$DATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"}]}},"scope-data-recursive":{"identifier":"scope-data-recursive","description":"This scope permits recursive access to the complete `$DATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"},{"path":"$DATA/**"}]}},"scope-desktop":{"identifier":"scope-desktop","description":"This scope permits access to all files and list content of top level directories in the `$DESKTOP` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"},{"path":"$DESKTOP/*"}]}},"scope-desktop-index":{"identifier":"scope-desktop-index","description":"This scope permits to list all files and folders in the `$DESKTOP`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"}]}},"scope-desktop-recursive":{"identifier":"scope-desktop-recursive","description":"This scope permits recursive access to the complete `$DESKTOP` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"},{"path":"$DESKTOP/**"}]}},"scope-document":{"identifier":"scope-document","description":"This scope permits access to all files and list content of top level directories in the `$DOCUMENT` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"},{"path":"$DOCUMENT/*"}]}},"scope-document-index":{"identifier":"scope-document-index","description":"This scope permits to list all files and folders in the `$DOCUMENT`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"}]}},"scope-document-recursive":{"identifier":"scope-document-recursive","description":"This scope permits recursive access to the complete `$DOCUMENT` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"},{"path":"$DOCUMENT/**"}]}},"scope-download":{"identifier":"scope-download","description":"This scope permits access to all files and list content of top level directories in the `$DOWNLOAD` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"},{"path":"$DOWNLOAD/*"}]}},"scope-download-index":{"identifier":"scope-download-index","description":"This scope permits to list all files and folders in the `$DOWNLOAD`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"}]}},"scope-download-recursive":{"identifier":"scope-download-recursive","description":"This scope permits recursive access to the complete `$DOWNLOAD` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"},{"path":"$DOWNLOAD/**"}]}},"scope-exe":{"identifier":"scope-exe","description":"This scope permits access to all files and list content of top level directories in the `$EXE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"},{"path":"$EXE/*"}]}},"scope-exe-index":{"identifier":"scope-exe-index","description":"This scope permits to list all files and folders in the `$EXE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"}]}},"scope-exe-recursive":{"identifier":"scope-exe-recursive","description":"This scope permits recursive access to the complete `$EXE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"},{"path":"$EXE/**"}]}},"scope-font":{"identifier":"scope-font","description":"This scope permits access to all files and list content of top level directories in the `$FONT` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"},{"path":"$FONT/*"}]}},"scope-font-index":{"identifier":"scope-font-index","description":"This scope permits to list all files and folders in the `$FONT`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"}]}},"scope-font-recursive":{"identifier":"scope-font-recursive","description":"This scope permits recursive access to the complete `$FONT` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"},{"path":"$FONT/**"}]}},"scope-home":{"identifier":"scope-home","description":"This scope permits access to all files and list content of top level directories in the `$HOME` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"},{"path":"$HOME/*"}]}},"scope-home-index":{"identifier":"scope-home-index","description":"This scope permits to list all files and folders in the `$HOME`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"}]}},"scope-home-recursive":{"identifier":"scope-home-recursive","description":"This scope permits recursive access to the complete `$HOME` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"},{"path":"$HOME/**"}]}},"scope-localdata":{"identifier":"scope-localdata","description":"This scope permits access to all files and list content of top level directories in the `$LOCALDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"},{"path":"$LOCALDATA/*"}]}},"scope-localdata-index":{"identifier":"scope-localdata-index","description":"This scope permits to list all files and folders in the `$LOCALDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"}]}},"scope-localdata-recursive":{"identifier":"scope-localdata-recursive","description":"This scope permits recursive access to the complete `$LOCALDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"},{"path":"$LOCALDATA/**"}]}},"scope-log":{"identifier":"scope-log","description":"This scope permits access to all files and list content of top level directories in the `$LOG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"},{"path":"$LOG/*"}]}},"scope-log-index":{"identifier":"scope-log-index","description":"This scope permits to list all files and folders in the `$LOG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"}]}},"scope-log-recursive":{"identifier":"scope-log-recursive","description":"This scope permits recursive access to the complete `$LOG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"},{"path":"$LOG/**"}]}},"scope-picture":{"identifier":"scope-picture","description":"This scope permits access to all files and list content of top level directories in the `$PICTURE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"},{"path":"$PICTURE/*"}]}},"scope-picture-index":{"identifier":"scope-picture-index","description":"This scope permits to list all files and folders in the `$PICTURE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"}]}},"scope-picture-recursive":{"identifier":"scope-picture-recursive","description":"This scope permits recursive access to the complete `$PICTURE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"},{"path":"$PICTURE/**"}]}},"scope-public":{"identifier":"scope-public","description":"This scope permits access to all files and list content of top level directories in the `$PUBLIC` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"},{"path":"$PUBLIC/*"}]}},"scope-public-index":{"identifier":"scope-public-index","description":"This scope permits to list all files and folders in the `$PUBLIC`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"}]}},"scope-public-recursive":{"identifier":"scope-public-recursive","description":"This scope permits recursive access to the complete `$PUBLIC` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"},{"path":"$PUBLIC/**"}]}},"scope-resource":{"identifier":"scope-resource","description":"This scope permits access to all files and list content of top level directories in the `$RESOURCE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"},{"path":"$RESOURCE/*"}]}},"scope-resource-index":{"identifier":"scope-resource-index","description":"This scope permits to list all files and folders in the `$RESOURCE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"}]}},"scope-resource-recursive":{"identifier":"scope-resource-recursive","description":"This scope permits recursive access to the complete `$RESOURCE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"},{"path":"$RESOURCE/**"}]}},"scope-runtime":{"identifier":"scope-runtime","description":"This scope permits access to all files and list content of top level directories in the `$RUNTIME` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"},{"path":"$RUNTIME/*"}]}},"scope-runtime-index":{"identifier":"scope-runtime-index","description":"This scope permits to list all files and folders in the `$RUNTIME`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"}]}},"scope-runtime-recursive":{"identifier":"scope-runtime-recursive","description":"This scope permits recursive access to the complete `$RUNTIME` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"},{"path":"$RUNTIME/**"}]}},"scope-temp":{"identifier":"scope-temp","description":"This scope permits access to all files and list content of top level directories in the `$TEMP` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"},{"path":"$TEMP/*"}]}},"scope-temp-index":{"identifier":"scope-temp-index","description":"This scope permits to list all files and folders in the `$TEMP`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"}]}},"scope-temp-recursive":{"identifier":"scope-temp-recursive","description":"This scope permits recursive access to the complete `$TEMP` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"},{"path":"$TEMP/**"}]}},"scope-template":{"identifier":"scope-template","description":"This scope permits access to all files and list content of top level directories in the `$TEMPLATE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"},{"path":"$TEMPLATE/*"}]}},"scope-template-index":{"identifier":"scope-template-index","description":"This scope permits to list all files and folders in the `$TEMPLATE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"}]}},"scope-template-recursive":{"identifier":"scope-template-recursive","description":"This scope permits recursive access to the complete `$TEMPLATE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"},{"path":"$TEMPLATE/**"}]}},"scope-video":{"identifier":"scope-video","description":"This scope permits access to all files and list content of top level directories in the `$VIDEO` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"},{"path":"$VIDEO/*"}]}},"scope-video-index":{"identifier":"scope-video-index","description":"This scope permits to list all files and folders in the `$VIDEO`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"}]}},"scope-video-recursive":{"identifier":"scope-video-recursive","description":"This scope permits recursive access to the complete `$VIDEO` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"},{"path":"$VIDEO/**"}]}},"write-all":{"identifier":"write-all","description":"This enables all write related commands without any pre-configured accessible paths.","commands":{"allow":["mkdir","create","copy_file","remove","rename","truncate","ftruncate","write","write_file","write_text_file"],"deny":[]}},"write-files":{"identifier":"write-files","description":"This enables all file write related commands without any pre-configured accessible paths.","commands":{"allow":["create","copy_file","remove","rename","truncate","ftruncate","write","write_file","write_text_file"],"deny":[]}}},"permission_sets":{"allow-app-meta":{"identifier":"allow-app-meta","description":"This allows non-recursive read access to metadata of the application folders, including file listing and statistics.","permissions":["read-meta","scope-app-index"]},"allow-app-meta-recursive":{"identifier":"allow-app-meta-recursive","description":"This allows full recursive read access to metadata of the application folders, including file listing and statistics.","permissions":["read-meta","scope-app-recursive"]},"allow-app-read":{"identifier":"allow-app-read","description":"This allows non-recursive read access to the application folders.","permissions":["read-all","scope-app"]},"allow-app-read-recursive":{"identifier":"allow-app-read-recursive","description":"This allows full recursive read access to the complete application folders, files and subdirectories.","permissions":["read-all","scope-app-recursive"]},"allow-app-write":{"identifier":"allow-app-write","description":"This allows non-recursive write access to the application folders.","permissions":["write-all","scope-app"]},"allow-app-write-recursive":{"identifier":"allow-app-write-recursive","description":"This allows full recursive write access to the complete application folders, files and subdirectories.","permissions":["write-all","scope-app-recursive"]},"allow-appcache-meta":{"identifier":"allow-appcache-meta","description":"This allows non-recursive read access to metadata of the `$APPCACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-appcache-index"]},"allow-appcache-meta-recursive":{"identifier":"allow-appcache-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPCACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-appcache-recursive"]},"allow-appcache-read":{"identifier":"allow-appcache-read","description":"This allows non-recursive read access to the `$APPCACHE` folder.","permissions":["read-all","scope-appcache"]},"allow-appcache-read-recursive":{"identifier":"allow-appcache-read-recursive","description":"This allows full recursive read access to the complete `$APPCACHE` folder, files and subdirectories.","permissions":["read-all","scope-appcache-recursive"]},"allow-appcache-write":{"identifier":"allow-appcache-write","description":"This allows non-recursive write access to the `$APPCACHE` folder.","permissions":["write-all","scope-appcache"]},"allow-appcache-write-recursive":{"identifier":"allow-appcache-write-recursive","description":"This allows full recursive write access to the complete `$APPCACHE` folder, files and subdirectories.","permissions":["write-all","scope-appcache-recursive"]},"allow-appconfig-meta":{"identifier":"allow-appconfig-meta","description":"This allows non-recursive read access to metadata of the `$APPCONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-appconfig-index"]},"allow-appconfig-meta-recursive":{"identifier":"allow-appconfig-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPCONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-appconfig-recursive"]},"allow-appconfig-read":{"identifier":"allow-appconfig-read","description":"This allows non-recursive read access to the `$APPCONFIG` folder.","permissions":["read-all","scope-appconfig"]},"allow-appconfig-read-recursive":{"identifier":"allow-appconfig-read-recursive","description":"This allows full recursive read access to the complete `$APPCONFIG` folder, files and subdirectories.","permissions":["read-all","scope-appconfig-recursive"]},"allow-appconfig-write":{"identifier":"allow-appconfig-write","description":"This allows non-recursive write access to the `$APPCONFIG` folder.","permissions":["write-all","scope-appconfig"]},"allow-appconfig-write-recursive":{"identifier":"allow-appconfig-write-recursive","description":"This allows full recursive write access to the complete `$APPCONFIG` folder, files and subdirectories.","permissions":["write-all","scope-appconfig-recursive"]},"allow-appdata-meta":{"identifier":"allow-appdata-meta","description":"This allows non-recursive read access to metadata of the `$APPDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-appdata-index"]},"allow-appdata-meta-recursive":{"identifier":"allow-appdata-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-appdata-recursive"]},"allow-appdata-read":{"identifier":"allow-appdata-read","description":"This allows non-recursive read access to the `$APPDATA` folder.","permissions":["read-all","scope-appdata"]},"allow-appdata-read-recursive":{"identifier":"allow-appdata-read-recursive","description":"This allows full recursive read access to the complete `$APPDATA` folder, files and subdirectories.","permissions":["read-all","scope-appdata-recursive"]},"allow-appdata-write":{"identifier":"allow-appdata-write","description":"This allows non-recursive write access to the `$APPDATA` folder.","permissions":["write-all","scope-appdata"]},"allow-appdata-write-recursive":{"identifier":"allow-appdata-write-recursive","description":"This allows full recursive write access to the complete `$APPDATA` folder, files and subdirectories.","permissions":["write-all","scope-appdata-recursive"]},"allow-applocaldata-meta":{"identifier":"allow-applocaldata-meta","description":"This allows non-recursive read access to metadata of the `$APPLOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-applocaldata-index"]},"allow-applocaldata-meta-recursive":{"identifier":"allow-applocaldata-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPLOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-applocaldata-recursive"]},"allow-applocaldata-read":{"identifier":"allow-applocaldata-read","description":"This allows non-recursive read access to the `$APPLOCALDATA` folder.","permissions":["read-all","scope-applocaldata"]},"allow-applocaldata-read-recursive":{"identifier":"allow-applocaldata-read-recursive","description":"This allows full recursive read access to the complete `$APPLOCALDATA` folder, files and subdirectories.","permissions":["read-all","scope-applocaldata-recursive"]},"allow-applocaldata-write":{"identifier":"allow-applocaldata-write","description":"This allows non-recursive write access to the `$APPLOCALDATA` folder.","permissions":["write-all","scope-applocaldata"]},"allow-applocaldata-write-recursive":{"identifier":"allow-applocaldata-write-recursive","description":"This allows full recursive write access to the complete `$APPLOCALDATA` folder, files and subdirectories.","permissions":["write-all","scope-applocaldata-recursive"]},"allow-applog-meta":{"identifier":"allow-applog-meta","description":"This allows non-recursive read access to metadata of the `$APPLOG` folder, including file listing and statistics.","permissions":["read-meta","scope-applog-index"]},"allow-applog-meta-recursive":{"identifier":"allow-applog-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPLOG` folder, including file listing and statistics.","permissions":["read-meta","scope-applog-recursive"]},"allow-applog-read":{"identifier":"allow-applog-read","description":"This allows non-recursive read access to the `$APPLOG` folder.","permissions":["read-all","scope-applog"]},"allow-applog-read-recursive":{"identifier":"allow-applog-read-recursive","description":"This allows full recursive read access to the complete `$APPLOG` folder, files and subdirectories.","permissions":["read-all","scope-applog-recursive"]},"allow-applog-write":{"identifier":"allow-applog-write","description":"This allows non-recursive write access to the `$APPLOG` folder.","permissions":["write-all","scope-applog"]},"allow-applog-write-recursive":{"identifier":"allow-applog-write-recursive","description":"This allows full recursive write access to the complete `$APPLOG` folder, files and subdirectories.","permissions":["write-all","scope-applog-recursive"]},"allow-audio-meta":{"identifier":"allow-audio-meta","description":"This allows non-recursive read access to metadata of the `$AUDIO` folder, including file listing and statistics.","permissions":["read-meta","scope-audio-index"]},"allow-audio-meta-recursive":{"identifier":"allow-audio-meta-recursive","description":"This allows full recursive read access to metadata of the `$AUDIO` folder, including file listing and statistics.","permissions":["read-meta","scope-audio-recursive"]},"allow-audio-read":{"identifier":"allow-audio-read","description":"This allows non-recursive read access to the `$AUDIO` folder.","permissions":["read-all","scope-audio"]},"allow-audio-read-recursive":{"identifier":"allow-audio-read-recursive","description":"This allows full recursive read access to the complete `$AUDIO` folder, files and subdirectories.","permissions":["read-all","scope-audio-recursive"]},"allow-audio-write":{"identifier":"allow-audio-write","description":"This allows non-recursive write access to the `$AUDIO` folder.","permissions":["write-all","scope-audio"]},"allow-audio-write-recursive":{"identifier":"allow-audio-write-recursive","description":"This allows full recursive write access to the complete `$AUDIO` folder, files and subdirectories.","permissions":["write-all","scope-audio-recursive"]},"allow-cache-meta":{"identifier":"allow-cache-meta","description":"This allows non-recursive read access to metadata of the `$CACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-cache-index"]},"allow-cache-meta-recursive":{"identifier":"allow-cache-meta-recursive","description":"This allows full recursive read access to metadata of the `$CACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-cache-recursive"]},"allow-cache-read":{"identifier":"allow-cache-read","description":"This allows non-recursive read access to the `$CACHE` folder.","permissions":["read-all","scope-cache"]},"allow-cache-read-recursive":{"identifier":"allow-cache-read-recursive","description":"This allows full recursive read access to the complete `$CACHE` folder, files and subdirectories.","permissions":["read-all","scope-cache-recursive"]},"allow-cache-write":{"identifier":"allow-cache-write","description":"This allows non-recursive write access to the `$CACHE` folder.","permissions":["write-all","scope-cache"]},"allow-cache-write-recursive":{"identifier":"allow-cache-write-recursive","description":"This allows full recursive write access to the complete `$CACHE` folder, files and subdirectories.","permissions":["write-all","scope-cache-recursive"]},"allow-config-meta":{"identifier":"allow-config-meta","description":"This allows non-recursive read access to metadata of the `$CONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-config-index"]},"allow-config-meta-recursive":{"identifier":"allow-config-meta-recursive","description":"This allows full recursive read access to metadata of the `$CONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-config-recursive"]},"allow-config-read":{"identifier":"allow-config-read","description":"This allows non-recursive read access to the `$CONFIG` folder.","permissions":["read-all","scope-config"]},"allow-config-read-recursive":{"identifier":"allow-config-read-recursive","description":"This allows full recursive read access to the complete `$CONFIG` folder, files and subdirectories.","permissions":["read-all","scope-config-recursive"]},"allow-config-write":{"identifier":"allow-config-write","description":"This allows non-recursive write access to the `$CONFIG` folder.","permissions":["write-all","scope-config"]},"allow-config-write-recursive":{"identifier":"allow-config-write-recursive","description":"This allows full recursive write access to the complete `$CONFIG` folder, files and subdirectories.","permissions":["write-all","scope-config-recursive"]},"allow-data-meta":{"identifier":"allow-data-meta","description":"This allows non-recursive read access to metadata of the `$DATA` folder, including file listing and statistics.","permissions":["read-meta","scope-data-index"]},"allow-data-meta-recursive":{"identifier":"allow-data-meta-recursive","description":"This allows full recursive read access to metadata of the `$DATA` folder, including file listing and statistics.","permissions":["read-meta","scope-data-recursive"]},"allow-data-read":{"identifier":"allow-data-read","description":"This allows non-recursive read access to the `$DATA` folder.","permissions":["read-all","scope-data"]},"allow-data-read-recursive":{"identifier":"allow-data-read-recursive","description":"This allows full recursive read access to the complete `$DATA` folder, files and subdirectories.","permissions":["read-all","scope-data-recursive"]},"allow-data-write":{"identifier":"allow-data-write","description":"This allows non-recursive write access to the `$DATA` folder.","permissions":["write-all","scope-data"]},"allow-data-write-recursive":{"identifier":"allow-data-write-recursive","description":"This allows full recursive write access to the complete `$DATA` folder, files and subdirectories.","permissions":["write-all","scope-data-recursive"]},"allow-desktop-meta":{"identifier":"allow-desktop-meta","description":"This allows non-recursive read access to metadata of the `$DESKTOP` folder, including file listing and statistics.","permissions":["read-meta","scope-desktop-index"]},"allow-desktop-meta-recursive":{"identifier":"allow-desktop-meta-recursive","description":"This allows full recursive read access to metadata of the `$DESKTOP` folder, including file listing and statistics.","permissions":["read-meta","scope-desktop-recursive"]},"allow-desktop-read":{"identifier":"allow-desktop-read","description":"This allows non-recursive read access to the `$DESKTOP` folder.","permissions":["read-all","scope-desktop"]},"allow-desktop-read-recursive":{"identifier":"allow-desktop-read-recursive","description":"This allows full recursive read access to the complete `$DESKTOP` folder, files and subdirectories.","permissions":["read-all","scope-desktop-recursive"]},"allow-desktop-write":{"identifier":"allow-desktop-write","description":"This allows non-recursive write access to the `$DESKTOP` folder.","permissions":["write-all","scope-desktop"]},"allow-desktop-write-recursive":{"identifier":"allow-desktop-write-recursive","description":"This allows full recursive write access to the complete `$DESKTOP` folder, files and subdirectories.","permissions":["write-all","scope-desktop-recursive"]},"allow-document-meta":{"identifier":"allow-document-meta","description":"This allows non-recursive read access to metadata of the `$DOCUMENT` folder, including file listing and statistics.","permissions":["read-meta","scope-document-index"]},"allow-document-meta-recursive":{"identifier":"allow-document-meta-recursive","description":"This allows full recursive read access to metadata of the `$DOCUMENT` folder, including file listing and statistics.","permissions":["read-meta","scope-document-recursive"]},"allow-document-read":{"identifier":"allow-document-read","description":"This allows non-recursive read access to the `$DOCUMENT` folder.","permissions":["read-all","scope-document"]},"allow-document-read-recursive":{"identifier":"allow-document-read-recursive","description":"This allows full recursive read access to the complete `$DOCUMENT` folder, files and subdirectories.","permissions":["read-all","scope-document-recursive"]},"allow-document-write":{"identifier":"allow-document-write","description":"This allows non-recursive write access to the `$DOCUMENT` folder.","permissions":["write-all","scope-document"]},"allow-document-write-recursive":{"identifier":"allow-document-write-recursive","description":"This allows full recursive write access to the complete `$DOCUMENT` folder, files and subdirectories.","permissions":["write-all","scope-document-recursive"]},"allow-download-meta":{"identifier":"allow-download-meta","description":"This allows non-recursive read access to metadata of the `$DOWNLOAD` folder, including file listing and statistics.","permissions":["read-meta","scope-download-index"]},"allow-download-meta-recursive":{"identifier":"allow-download-meta-recursive","description":"This allows full recursive read access to metadata of the `$DOWNLOAD` folder, including file listing and statistics.","permissions":["read-meta","scope-download-recursive"]},"allow-download-read":{"identifier":"allow-download-read","description":"This allows non-recursive read access to the `$DOWNLOAD` folder.","permissions":["read-all","scope-download"]},"allow-download-read-recursive":{"identifier":"allow-download-read-recursive","description":"This allows full recursive read access to the complete `$DOWNLOAD` folder, files and subdirectories.","permissions":["read-all","scope-download-recursive"]},"allow-download-write":{"identifier":"allow-download-write","description":"This allows non-recursive write access to the `$DOWNLOAD` folder.","permissions":["write-all","scope-download"]},"allow-download-write-recursive":{"identifier":"allow-download-write-recursive","description":"This allows full recursive write access to the complete `$DOWNLOAD` folder, files and subdirectories.","permissions":["write-all","scope-download-recursive"]},"allow-exe-meta":{"identifier":"allow-exe-meta","description":"This allows non-recursive read access to metadata of the `$EXE` folder, including file listing and statistics.","permissions":["read-meta","scope-exe-index"]},"allow-exe-meta-recursive":{"identifier":"allow-exe-meta-recursive","description":"This allows full recursive read access to metadata of the `$EXE` folder, including file listing and statistics.","permissions":["read-meta","scope-exe-recursive"]},"allow-exe-read":{"identifier":"allow-exe-read","description":"This allows non-recursive read access to the `$EXE` folder.","permissions":["read-all","scope-exe"]},"allow-exe-read-recursive":{"identifier":"allow-exe-read-recursive","description":"This allows full recursive read access to the complete `$EXE` folder, files and subdirectories.","permissions":["read-all","scope-exe-recursive"]},"allow-exe-write":{"identifier":"allow-exe-write","description":"This allows non-recursive write access to the `$EXE` folder.","permissions":["write-all","scope-exe"]},"allow-exe-write-recursive":{"identifier":"allow-exe-write-recursive","description":"This allows full recursive write access to the complete `$EXE` folder, files and subdirectories.","permissions":["write-all","scope-exe-recursive"]},"allow-font-meta":{"identifier":"allow-font-meta","description":"This allows non-recursive read access to metadata of the `$FONT` folder, including file listing and statistics.","permissions":["read-meta","scope-font-index"]},"allow-font-meta-recursive":{"identifier":"allow-font-meta-recursive","description":"This allows full recursive read access to metadata of the `$FONT` folder, including file listing and statistics.","permissions":["read-meta","scope-font-recursive"]},"allow-font-read":{"identifier":"allow-font-read","description":"This allows non-recursive read access to the `$FONT` folder.","permissions":["read-all","scope-font"]},"allow-font-read-recursive":{"identifier":"allow-font-read-recursive","description":"This allows full recursive read access to the complete `$FONT` folder, files and subdirectories.","permissions":["read-all","scope-font-recursive"]},"allow-font-write":{"identifier":"allow-font-write","description":"This allows non-recursive write access to the `$FONT` folder.","permissions":["write-all","scope-font"]},"allow-font-write-recursive":{"identifier":"allow-font-write-recursive","description":"This allows full recursive write access to the complete `$FONT` folder, files and subdirectories.","permissions":["write-all","scope-font-recursive"]},"allow-home-meta":{"identifier":"allow-home-meta","description":"This allows non-recursive read access to metadata of the `$HOME` folder, including file listing and statistics.","permissions":["read-meta","scope-home-index"]},"allow-home-meta-recursive":{"identifier":"allow-home-meta-recursive","description":"This allows full recursive read access to metadata of the `$HOME` folder, including file listing and statistics.","permissions":["read-meta","scope-home-recursive"]},"allow-home-read":{"identifier":"allow-home-read","description":"This allows non-recursive read access to the `$HOME` folder.","permissions":["read-all","scope-home"]},"allow-home-read-recursive":{"identifier":"allow-home-read-recursive","description":"This allows full recursive read access to the complete `$HOME` folder, files and subdirectories.","permissions":["read-all","scope-home-recursive"]},"allow-home-write":{"identifier":"allow-home-write","description":"This allows non-recursive write access to the `$HOME` folder.","permissions":["write-all","scope-home"]},"allow-home-write-recursive":{"identifier":"allow-home-write-recursive","description":"This allows full recursive write access to the complete `$HOME` folder, files and subdirectories.","permissions":["write-all","scope-home-recursive"]},"allow-localdata-meta":{"identifier":"allow-localdata-meta","description":"This allows non-recursive read access to metadata of the `$LOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-localdata-index"]},"allow-localdata-meta-recursive":{"identifier":"allow-localdata-meta-recursive","description":"This allows full recursive read access to metadata of the `$LOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-localdata-recursive"]},"allow-localdata-read":{"identifier":"allow-localdata-read","description":"This allows non-recursive read access to the `$LOCALDATA` folder.","permissions":["read-all","scope-localdata"]},"allow-localdata-read-recursive":{"identifier":"allow-localdata-read-recursive","description":"This allows full recursive read access to the complete `$LOCALDATA` folder, files and subdirectories.","permissions":["read-all","scope-localdata-recursive"]},"allow-localdata-write":{"identifier":"allow-localdata-write","description":"This allows non-recursive write access to the `$LOCALDATA` folder.","permissions":["write-all","scope-localdata"]},"allow-localdata-write-recursive":{"identifier":"allow-localdata-write-recursive","description":"This allows full recursive write access to the complete `$LOCALDATA` folder, files and subdirectories.","permissions":["write-all","scope-localdata-recursive"]},"allow-log-meta":{"identifier":"allow-log-meta","description":"This allows non-recursive read access to metadata of the `$LOG` folder, including file listing and statistics.","permissions":["read-meta","scope-log-index"]},"allow-log-meta-recursive":{"identifier":"allow-log-meta-recursive","description":"This allows full recursive read access to metadata of the `$LOG` folder, including file listing and statistics.","permissions":["read-meta","scope-log-recursive"]},"allow-log-read":{"identifier":"allow-log-read","description":"This allows non-recursive read access to the `$LOG` folder.","permissions":["read-all","scope-log"]},"allow-log-read-recursive":{"identifier":"allow-log-read-recursive","description":"This allows full recursive read access to the complete `$LOG` folder, files and subdirectories.","permissions":["read-all","scope-log-recursive"]},"allow-log-write":{"identifier":"allow-log-write","description":"This allows non-recursive write access to the `$LOG` folder.","permissions":["write-all","scope-log"]},"allow-log-write-recursive":{"identifier":"allow-log-write-recursive","description":"This allows full recursive write access to the complete `$LOG` folder, files and subdirectories.","permissions":["write-all","scope-log-recursive"]},"allow-picture-meta":{"identifier":"allow-picture-meta","description":"This allows non-recursive read access to metadata of the `$PICTURE` folder, including file listing and statistics.","permissions":["read-meta","scope-picture-index"]},"allow-picture-meta-recursive":{"identifier":"allow-picture-meta-recursive","description":"This allows full recursive read access to metadata of the `$PICTURE` folder, including file listing and statistics.","permissions":["read-meta","scope-picture-recursive"]},"allow-picture-read":{"identifier":"allow-picture-read","description":"This allows non-recursive read access to the `$PICTURE` folder.","permissions":["read-all","scope-picture"]},"allow-picture-read-recursive":{"identifier":"allow-picture-read-recursive","description":"This allows full recursive read access to the complete `$PICTURE` folder, files and subdirectories.","permissions":["read-all","scope-picture-recursive"]},"allow-picture-write":{"identifier":"allow-picture-write","description":"This allows non-recursive write access to the `$PICTURE` folder.","permissions":["write-all","scope-picture"]},"allow-picture-write-recursive":{"identifier":"allow-picture-write-recursive","description":"This allows full recursive write access to the complete `$PICTURE` folder, files and subdirectories.","permissions":["write-all","scope-picture-recursive"]},"allow-public-meta":{"identifier":"allow-public-meta","description":"This allows non-recursive read access to metadata of the `$PUBLIC` folder, including file listing and statistics.","permissions":["read-meta","scope-public-index"]},"allow-public-meta-recursive":{"identifier":"allow-public-meta-recursive","description":"This allows full recursive read access to metadata of the `$PUBLIC` folder, including file listing and statistics.","permissions":["read-meta","scope-public-recursive"]},"allow-public-read":{"identifier":"allow-public-read","description":"This allows non-recursive read access to the `$PUBLIC` folder.","permissions":["read-all","scope-public"]},"allow-public-read-recursive":{"identifier":"allow-public-read-recursive","description":"This allows full recursive read access to the complete `$PUBLIC` folder, files and subdirectories.","permissions":["read-all","scope-public-recursive"]},"allow-public-write":{"identifier":"allow-public-write","description":"This allows non-recursive write access to the `$PUBLIC` folder.","permissions":["write-all","scope-public"]},"allow-public-write-recursive":{"identifier":"allow-public-write-recursive","description":"This allows full recursive write access to the complete `$PUBLIC` folder, files and subdirectories.","permissions":["write-all","scope-public-recursive"]},"allow-resource-meta":{"identifier":"allow-resource-meta","description":"This allows non-recursive read access to metadata of the `$RESOURCE` folder, including file listing and statistics.","permissions":["read-meta","scope-resource-index"]},"allow-resource-meta-recursive":{"identifier":"allow-resource-meta-recursive","description":"This allows full recursive read access to metadata of the `$RESOURCE` folder, including file listing and statistics.","permissions":["read-meta","scope-resource-recursive"]},"allow-resource-read":{"identifier":"allow-resource-read","description":"This allows non-recursive read access to the `$RESOURCE` folder.","permissions":["read-all","scope-resource"]},"allow-resource-read-recursive":{"identifier":"allow-resource-read-recursive","description":"This allows full recursive read access to the complete `$RESOURCE` folder, files and subdirectories.","permissions":["read-all","scope-resource-recursive"]},"allow-resource-write":{"identifier":"allow-resource-write","description":"This allows non-recursive write access to the `$RESOURCE` folder.","permissions":["write-all","scope-resource"]},"allow-resource-write-recursive":{"identifier":"allow-resource-write-recursive","description":"This allows full recursive write access to the complete `$RESOURCE` folder, files and subdirectories.","permissions":["write-all","scope-resource-recursive"]},"allow-runtime-meta":{"identifier":"allow-runtime-meta","description":"This allows non-recursive read access to metadata of the `$RUNTIME` folder, including file listing and statistics.","permissions":["read-meta","scope-runtime-index"]},"allow-runtime-meta-recursive":{"identifier":"allow-runtime-meta-recursive","description":"This allows full recursive read access to metadata of the `$RUNTIME` folder, including file listing and statistics.","permissions":["read-meta","scope-runtime-recursive"]},"allow-runtime-read":{"identifier":"allow-runtime-read","description":"This allows non-recursive read access to the `$RUNTIME` folder.","permissions":["read-all","scope-runtime"]},"allow-runtime-read-recursive":{"identifier":"allow-runtime-read-recursive","description":"This allows full recursive read access to the complete `$RUNTIME` folder, files and subdirectories.","permissions":["read-all","scope-runtime-recursive"]},"allow-runtime-write":{"identifier":"allow-runtime-write","description":"This allows non-recursive write access to the `$RUNTIME` folder.","permissions":["write-all","scope-runtime"]},"allow-runtime-write-recursive":{"identifier":"allow-runtime-write-recursive","description":"This allows full recursive write access to the complete `$RUNTIME` folder, files and subdirectories.","permissions":["write-all","scope-runtime-recursive"]},"allow-temp-meta":{"identifier":"allow-temp-meta","description":"This allows non-recursive read access to metadata of the `$TEMP` folder, including file listing and statistics.","permissions":["read-meta","scope-temp-index"]},"allow-temp-meta-recursive":{"identifier":"allow-temp-meta-recursive","description":"This allows full recursive read access to metadata of the `$TEMP` folder, including file listing and statistics.","permissions":["read-meta","scope-temp-recursive"]},"allow-temp-read":{"identifier":"allow-temp-read","description":"This allows non-recursive read access to the `$TEMP` folder.","permissions":["read-all","scope-temp"]},"allow-temp-read-recursive":{"identifier":"allow-temp-read-recursive","description":"This allows full recursive read access to the complete `$TEMP` folder, files and subdirectories.","permissions":["read-all","scope-temp-recursive"]},"allow-temp-write":{"identifier":"allow-temp-write","description":"This allows non-recursive write access to the `$TEMP` folder.","permissions":["write-all","scope-temp"]},"allow-temp-write-recursive":{"identifier":"allow-temp-write-recursive","description":"This allows full recursive write access to the complete `$TEMP` folder, files and subdirectories.","permissions":["write-all","scope-temp-recursive"]},"allow-template-meta":{"identifier":"allow-template-meta","description":"This allows non-recursive read access to metadata of the `$TEMPLATE` folder, including file listing and statistics.","permissions":["read-meta","scope-template-index"]},"allow-template-meta-recursive":{"identifier":"allow-template-meta-recursive","description":"This allows full recursive read access to metadata of the `$TEMPLATE` folder, including file listing and statistics.","permissions":["read-meta","scope-template-recursive"]},"allow-template-read":{"identifier":"allow-template-read","description":"This allows non-recursive read access to the `$TEMPLATE` folder.","permissions":["read-all","scope-template"]},"allow-template-read-recursive":{"identifier":"allow-template-read-recursive","description":"This allows full recursive read access to the complete `$TEMPLATE` folder, files and subdirectories.","permissions":["read-all","scope-template-recursive"]},"allow-template-write":{"identifier":"allow-template-write","description":"This allows non-recursive write access to the `$TEMPLATE` folder.","permissions":["write-all","scope-template"]},"allow-template-write-recursive":{"identifier":"allow-template-write-recursive","description":"This allows full recursive write access to the complete `$TEMPLATE` folder, files and subdirectories.","permissions":["write-all","scope-template-recursive"]},"allow-video-meta":{"identifier":"allow-video-meta","description":"This allows non-recursive read access to metadata of the `$VIDEO` folder, including file listing and statistics.","permissions":["read-meta","scope-video-index"]},"allow-video-meta-recursive":{"identifier":"allow-video-meta-recursive","description":"This allows full recursive read access to metadata of the `$VIDEO` folder, including file listing and statistics.","permissions":["read-meta","scope-video-recursive"]},"allow-video-read":{"identifier":"allow-video-read","description":"This allows non-recursive read access to the `$VIDEO` folder.","permissions":["read-all","scope-video"]},"allow-video-read-recursive":{"identifier":"allow-video-read-recursive","description":"This allows full recursive read access to the complete `$VIDEO` folder, files and subdirectories.","permissions":["read-all","scope-video-recursive"]},"allow-video-write":{"identifier":"allow-video-write","description":"This allows non-recursive write access to the `$VIDEO` folder.","permissions":["write-all","scope-video"]},"allow-video-write-recursive":{"identifier":"allow-video-write-recursive","description":"This allows full recursive write access to the complete `$VIDEO` folder, files and subdirectories.","permissions":["write-all","scope-video-recursive"]},"deny-default":{"identifier":"deny-default","description":"This denies access to dangerous Tauri relevant files and folders by default.","permissions":["deny-webview-data-linux","deny-webview-data-windows"]}},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"description":"A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},{"properties":{"path":{"description":"A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"description":"FS scope entry.","title":"FsScopeEntry"}},"log":{"default_permission":{"identifier":"default","description":"Allows the log command","permissions":["allow-log"]},"permissions":{"allow-log":{"identifier":"allow-log","description":"Enables the log command without any pre-configured scope.","commands":{"allow":["log"],"deny":[]}},"deny-log":{"identifier":"deny-log","description":"Denies the log command without any pre-configured scope.","commands":{"allow":[],"deny":["log"]}}},"permission_sets":{},"global_scope_schema":null},"opener":{"default_permission":{"identifier":"default","description":"This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer","permissions":["allow-open-url","allow-reveal-item-in-dir","allow-default-urls"]},"permissions":{"allow-default-urls":{"identifier":"allow-default-urls","description":"This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"url":"mailto:*"},{"url":"tel:*"},{"url":"http://*"},{"url":"https://*"}]}},"allow-open-path":{"identifier":"allow-open-path","description":"Enables the open_path command without any pre-configured scope.","commands":{"allow":["open_path"],"deny":[]}},"allow-open-url":{"identifier":"allow-open-url","description":"Enables the open_url command without any pre-configured scope.","commands":{"allow":["open_url"],"deny":[]}},"allow-reveal-item-in-dir":{"identifier":"allow-reveal-item-in-dir","description":"Enables the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":["reveal_item_in_dir"],"deny":[]}},"deny-open-path":{"identifier":"deny-open-path","description":"Denies the open_path command without any pre-configured scope.","commands":{"allow":[],"deny":["open_path"]}},"deny-open-url":{"identifier":"deny-open-url","description":"Denies the open_url command without any pre-configured scope.","commands":{"allow":[],"deny":["open_url"]}},"deny-reveal-item-in-dir":{"identifier":"deny-reveal-item-in-dir","description":"Denies the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["reveal_item_in_dir"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this url with, for example: firefox."},"url":{"description":"A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.amrom.workers.dev/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"","type":"string"}},"required":["url"],"type":"object"},{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this path with, for example: xdg-open."},"path":{"description":"A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"definitions":{"Application":{"anyOf":[{"description":"Open in default application.","type":"null"},{"description":"If true, allow open with any application.","type":"boolean"},{"description":"Allow specific application to open with.","type":"string"}],"description":"Opener scope application."}},"description":"Opener scope entry.","title":"OpenerScopeEntry"}},"os":{"default_permission":{"identifier":"default","description":"This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n","permissions":["allow-arch","allow-exe-extension","allow-family","allow-locale","allow-os-type","allow-platform","allow-version"]},"permissions":{"allow-arch":{"identifier":"allow-arch","description":"Enables the arch command without any pre-configured scope.","commands":{"allow":["arch"],"deny":[]}},"allow-exe-extension":{"identifier":"allow-exe-extension","description":"Enables the exe_extension command without any pre-configured scope.","commands":{"allow":["exe_extension"],"deny":[]}},"allow-family":{"identifier":"allow-family","description":"Enables the family command without any pre-configured scope.","commands":{"allow":["family"],"deny":[]}},"allow-hostname":{"identifier":"allow-hostname","description":"Enables the hostname command without any pre-configured scope.","commands":{"allow":["hostname"],"deny":[]}},"allow-locale":{"identifier":"allow-locale","description":"Enables the locale command without any pre-configured scope.","commands":{"allow":["locale"],"deny":[]}},"allow-os-type":{"identifier":"allow-os-type","description":"Enables the os_type command without any pre-configured scope.","commands":{"allow":["os_type"],"deny":[]}},"allow-platform":{"identifier":"allow-platform","description":"Enables the platform command without any pre-configured scope.","commands":{"allow":["platform"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-arch":{"identifier":"deny-arch","description":"Denies the arch command without any pre-configured scope.","commands":{"allow":[],"deny":["arch"]}},"deny-exe-extension":{"identifier":"deny-exe-extension","description":"Denies the exe_extension command without any pre-configured scope.","commands":{"allow":[],"deny":["exe_extension"]}},"deny-family":{"identifier":"deny-family","description":"Denies the family command without any pre-configured scope.","commands":{"allow":[],"deny":["family"]}},"deny-hostname":{"identifier":"deny-hostname","description":"Denies the hostname command without any pre-configured scope.","commands":{"allow":[],"deny":["hostname"]}},"deny-locale":{"identifier":"deny-locale","description":"Denies the locale command without any pre-configured scope.","commands":{"allow":[],"deny":["locale"]}},"deny-os-type":{"identifier":"deny-os-type","description":"Denies the os_type command without any pre-configured scope.","commands":{"allow":[],"deny":["os_type"]}},"deny-platform":{"identifier":"deny-platform","description":"Denies the platform command without any pre-configured scope.","commands":{"allow":[],"deny":["platform"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"}},"required":["cmd","name"],"type":"object"},{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["name","sidecar"],"type":"object"}],"definitions":{"ShellScopeEntryAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"raw":{"default":false,"description":"Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.","type":"boolean"},"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellScopeEntryAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellScopeEntryAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"Shell scope entry.","title":"ShellScopeEntry"}},"updater":{"default_permission":{"identifier":"default","description":"This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n","permissions":["allow-check","allow-download","allow-install","allow-download-and-install"]},"permissions":{"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"allow-download":{"identifier":"allow-download","description":"Enables the download command without any pre-configured scope.","commands":{"allow":["download"],"deny":[]}},"allow-download-and-install":{"identifier":"allow-download-and-install","description":"Enables the download_and_install command without any pre-configured scope.","commands":{"allow":["download_and_install"],"deny":[]}},"allow-install":{"identifier":"allow-install","description":"Enables the install command without any pre-configured scope.","commands":{"allow":["install"],"deny":[]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}},"deny-download":{"identifier":"deny-download","description":"Denies the download command without any pre-configured scope.","commands":{"allow":[],"deny":["download"]}},"deny-download-and-install":{"identifier":"deny-download-and-install","description":"Denies the download_and_install command without any pre-configured scope.","commands":{"allow":[],"deny":["download_and_install"]}},"deny-install":{"identifier":"deny-install","description":"Denies the install command without any pre-configured scope.","commands":{"allow":[],"deny":["install"]}}},"permission_sets":{},"global_scope_schema":null},"window-state":{"default_permission":{"identifier":"default","description":"This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n","permissions":["allow-filename","allow-restore-state","allow-save-window-state"]},"permissions":{"allow-filename":{"identifier":"allow-filename","description":"Enables the filename command without any pre-configured scope.","commands":{"allow":["filename"],"deny":[]}},"allow-restore-state":{"identifier":"allow-restore-state","description":"Enables the restore_state command without any pre-configured scope.","commands":{"allow":["restore_state"],"deny":[]}},"allow-save-window-state":{"identifier":"allow-save-window-state","description":"Enables the save_window_state command without any pre-configured scope.","commands":{"allow":["save_window_state"],"deny":[]}},"deny-filename":{"identifier":"deny-filename","description":"Denies the filename command without any pre-configured scope.","commands":{"allow":[],"deny":["filename"]}},"deny-restore-state":{"identifier":"deny-restore-state","description":"Denies the restore_state command without any pre-configured scope.","commands":{"allow":[],"deny":["restore_state"]}},"deny-save-window-state":{"identifier":"deny-save-window-state","description":"Denies the save_window_state command without any pre-configured scope.","commands":{"allow":[],"deny":["save_window_state"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-git":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-add","allow-branch","allow-checkout","allow-commit","allow-delete-branch","allow-fetch-all","allow-initialize","allow-log","allow-merge-branch","allow-pull","allow-push","allow-status","allow-unstage"]},"permissions":{"allow-add":{"identifier":"allow-add","description":"Enables the add command without any pre-configured scope.","commands":{"allow":["add"],"deny":[]}},"allow-branch":{"identifier":"allow-branch","description":"Enables the branch command without any pre-configured scope.","commands":{"allow":["branch"],"deny":[]}},"allow-checkout":{"identifier":"allow-checkout","description":"Enables the checkout command without any pre-configured scope.","commands":{"allow":["checkout"],"deny":[]}},"allow-checkout-remote":{"identifier":"allow-checkout-remote","description":"Enables the checkout_remote command without any pre-configured scope.","commands":{"allow":["checkout_remote"],"deny":[]}},"allow-commit":{"identifier":"allow-commit","description":"Enables the commit command without any pre-configured scope.","commands":{"allow":["commit"],"deny":[]}},"allow-delete-branch":{"identifier":"allow-delete-branch","description":"Enables the delete_branch command without any pre-configured scope.","commands":{"allow":["delete_branch"],"deny":[]}},"allow-fetch-all":{"identifier":"allow-fetch-all","description":"Enables the fetch_all command without any pre-configured scope.","commands":{"allow":["fetch_all"],"deny":[]}},"allow-initialize":{"identifier":"allow-initialize","description":"Enables the initialize command without any pre-configured scope.","commands":{"allow":["initialize"],"deny":[]}},"allow-log":{"identifier":"allow-log","description":"Enables the log command without any pre-configured scope.","commands":{"allow":["log"],"deny":[]}},"allow-merge-branch":{"identifier":"allow-merge-branch","description":"Enables the merge_branch command without any pre-configured scope.","commands":{"allow":["merge_branch"],"deny":[]}},"allow-pull":{"identifier":"allow-pull","description":"Enables the pull command without any pre-configured scope.","commands":{"allow":["pull"],"deny":[]}},"allow-push":{"identifier":"allow-push","description":"Enables the push command without any pre-configured scope.","commands":{"allow":["push"],"deny":[]}},"allow-status":{"identifier":"allow-status","description":"Enables the status command without any pre-configured scope.","commands":{"allow":["status"],"deny":[]}},"allow-unstage":{"identifier":"allow-unstage","description":"Enables the unstage command without any pre-configured scope.","commands":{"allow":["unstage"],"deny":[]}},"deny-add":{"identifier":"deny-add","description":"Denies the add command without any pre-configured scope.","commands":{"allow":[],"deny":["add"]}},"deny-branch":{"identifier":"deny-branch","description":"Denies the branch command without any pre-configured scope.","commands":{"allow":[],"deny":["branch"]}},"deny-checkout":{"identifier":"deny-checkout","description":"Denies the checkout command without any pre-configured scope.","commands":{"allow":[],"deny":["checkout"]}},"deny-checkout-remote":{"identifier":"deny-checkout-remote","description":"Denies the checkout_remote command without any pre-configured scope.","commands":{"allow":[],"deny":["checkout_remote"]}},"deny-commit":{"identifier":"deny-commit","description":"Denies the commit command without any pre-configured scope.","commands":{"allow":[],"deny":["commit"]}},"deny-delete-branch":{"identifier":"deny-delete-branch","description":"Denies the delete_branch command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_branch"]}},"deny-fetch-all":{"identifier":"deny-fetch-all","description":"Denies the fetch_all command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_all"]}},"deny-initialize":{"identifier":"deny-initialize","description":"Denies the initialize command without any pre-configured scope.","commands":{"allow":[],"deny":["initialize"]}},"deny-log":{"identifier":"deny-log","description":"Denies the log command without any pre-configured scope.","commands":{"allow":[],"deny":["log"]}},"deny-merge-branch":{"identifier":"deny-merge-branch","description":"Denies the merge_branch command without any pre-configured scope.","commands":{"allow":[],"deny":["merge_branch"]}},"deny-pull":{"identifier":"deny-pull","description":"Denies the pull command without any pre-configured scope.","commands":{"allow":[],"deny":["pull"]}},"deny-push":{"identifier":"deny-push","description":"Denies the push command without any pre-configured scope.","commands":{"allow":[],"deny":["push"]}},"deny-status":{"identifier":"deny-status","description":"Denies the status command without any pre-configured scope.","commands":{"allow":[],"deny":["status"]}},"deny-unstage":{"identifier":"deny-unstage","description":"Denies the unstage command without any pre-configured scope.","commands":{"allow":[],"deny":["unstage"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-license":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-check","allow-activate","allow-deactivate"]},"permissions":{"allow-activate":{"identifier":"allow-activate","description":"Enables the activate command without any pre-configured scope.","commands":{"allow":["activate"],"deny":[]}},"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"allow-deactivate":{"identifier":"allow-deactivate","description":"Enables the deactivate command without any pre-configured scope.","commands":{"allow":["deactivate"],"deny":[]}},"deny-activate":{"identifier":"deny-activate","description":"Denies the activate command without any pre-configured scope.","commands":{"allow":[],"deny":["activate"]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}},"deny-deactivate":{"identifier":"deny-deactivate","description":"Denies the deactivate command without any pre-configured scope.","commands":{"allow":[],"deny":["deactivate"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-sync":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-calculate","allow-calculate-fs","allow-apply","allow-watch"]},"permissions":{"allow-apply":{"identifier":"allow-apply","description":"Enables the apply command without any pre-configured scope.","commands":{"allow":["apply"],"deny":[]}},"allow-calculate":{"identifier":"allow-calculate","description":"Enables the calculate command without any pre-configured scope.","commands":{"allow":["calculate"],"deny":[]}},"allow-calculate-fs":{"identifier":"allow-calculate-fs","description":"Enables the calculate_fs command without any pre-configured scope.","commands":{"allow":["calculate_fs"],"deny":[]}},"allow-watch":{"identifier":"allow-watch","description":"Enables the watch command without any pre-configured scope.","commands":{"allow":["watch"],"deny":[]}},"deny-apply":{"identifier":"deny-apply","description":"Denies the apply command without any pre-configured scope.","commands":{"allow":[],"deny":["apply"]}},"deny-calculate":{"identifier":"deny-calculate","description":"Denies the calculate command without any pre-configured scope.","commands":{"allow":[],"deny":["calculate"]}},"deny-calculate-fs":{"identifier":"deny-calculate-fs","description":"Denies the calculate_fs command without any pre-configured scope.","commands":{"allow":[],"deny":["calculate_fs"]}},"deny-watch":{"identifier":"deny-watch","description":"Denies the watch command without any pre-configured scope.","commands":{"allow":[],"deny":["watch"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-ws":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-close","allow-connect","allow-delete-connection","allow-delete-connections","allow-delete-request","allow-duplicate-request","allow-list-connections","allow-list-events","allow-list-requests","allow-send","allow-upsert-request"]},"permissions":{"allow-cancel":{"identifier":"allow-cancel","description":"Enables the cancel command without any pre-configured scope.","commands":{"allow":["cancel"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-connect":{"identifier":"allow-connect","description":"Enables the connect command without any pre-configured scope.","commands":{"allow":["connect"],"deny":[]}},"allow-delete-connection":{"identifier":"allow-delete-connection","description":"Enables the delete_connection command without any pre-configured scope.","commands":{"allow":["delete_connection"],"deny":[]}},"allow-delete-connections":{"identifier":"allow-delete-connections","description":"Enables the delete_connections command without any pre-configured scope.","commands":{"allow":["delete_connections"],"deny":[]}},"allow-delete-request":{"identifier":"allow-delete-request","description":"Enables the delete_request command without any pre-configured scope.","commands":{"allow":["delete_request"],"deny":[]}},"allow-duplicate-request":{"identifier":"allow-duplicate-request","description":"Enables the duplicate_request command without any pre-configured scope.","commands":{"allow":["duplicate_request"],"deny":[]}},"allow-list-connections":{"identifier":"allow-list-connections","description":"Enables the list_connections command without any pre-configured scope.","commands":{"allow":["list_connections"],"deny":[]}},"allow-list-events":{"identifier":"allow-list-events","description":"Enables the list_events command without any pre-configured scope.","commands":{"allow":["list_events"],"deny":[]}},"allow-list-requests":{"identifier":"allow-list-requests","description":"Enables the list_requests command without any pre-configured scope.","commands":{"allow":["list_requests"],"deny":[]}},"allow-list-websocket-connections":{"identifier":"allow-list-websocket-connections","description":"Enables the list_websocket_connections command without any pre-configured scope.","commands":{"allow":["list_websocket_connections"],"deny":[]}},"allow-list-websocket-requests":{"identifier":"allow-list-websocket-requests","description":"Enables the list_websocket_requests command without any pre-configured scope.","commands":{"allow":["list_websocket_requests"],"deny":[]}},"allow-send":{"identifier":"allow-send","description":"Enables the send command without any pre-configured scope.","commands":{"allow":["send"],"deny":[]}},"allow-upsert-request":{"identifier":"allow-upsert-request","description":"Enables the upsert_request command without any pre-configured scope.","commands":{"allow":["upsert_request"],"deny":[]}},"allow-upsert-websocket-request":{"identifier":"allow-upsert-websocket-request","description":"Enables the upsert_websocket_request command without any pre-configured scope.","commands":{"allow":["upsert_websocket_request"],"deny":[]}},"deny-cancel":{"identifier":"deny-cancel","description":"Denies the cancel command without any pre-configured scope.","commands":{"allow":[],"deny":["cancel"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-connect":{"identifier":"deny-connect","description":"Denies the connect command without any pre-configured scope.","commands":{"allow":[],"deny":["connect"]}},"deny-delete-connection":{"identifier":"deny-delete-connection","description":"Denies the delete_connection command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_connection"]}},"deny-delete-connections":{"identifier":"deny-delete-connections","description":"Denies the delete_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_connections"]}},"deny-delete-request":{"identifier":"deny-delete-request","description":"Denies the delete_request command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_request"]}},"deny-duplicate-request":{"identifier":"deny-duplicate-request","description":"Denies the duplicate_request command without any pre-configured scope.","commands":{"allow":[],"deny":["duplicate_request"]}},"deny-list-connections":{"identifier":"deny-list-connections","description":"Denies the list_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["list_connections"]}},"deny-list-events":{"identifier":"deny-list-events","description":"Denies the list_events command without any pre-configured scope.","commands":{"allow":[],"deny":["list_events"]}},"deny-list-requests":{"identifier":"deny-list-requests","description":"Denies the list_requests command without any pre-configured scope.","commands":{"allow":[],"deny":["list_requests"]}},"deny-list-websocket-connections":{"identifier":"deny-list-websocket-connections","description":"Denies the list_websocket_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["list_websocket_connections"]}},"deny-list-websocket-requests":{"identifier":"deny-list-websocket-requests","description":"Denies the list_websocket_requests command without any pre-configured scope.","commands":{"allow":[],"deny":["list_websocket_requests"]}},"deny-send":{"identifier":"deny-send","description":"Denies the send command without any pre-configured scope.","commands":{"allow":[],"deny":["send"]}},"deny-upsert-request":{"identifier":"deny-upsert-request","description":"Denies the upsert_request command without any pre-configured scope.","commands":{"allow":[],"deny":["upsert_request"]}},"deny-upsert-websocket-request":{"identifier":"deny-upsert-websocket-request","description":"Denies the upsert_websocket_request command without any pre-configured scope.","commands":{"allow":[],"deny":["upsert_websocket_request"]}}},"permission_sets":{},"global_scope_schema":null}} \ No newline at end of file diff --git a/src-tauri/gen/schemas/desktop-schema.json b/src-tauri/gen/schemas/desktop-schema.json index dc693cf11..66760a062 100644 --- a/src-tauri/gen/schemas/desktop-schema.json +++ b/src-tauri/gen/schemas/desktop-schema.json @@ -5572,6 +5572,11 @@ "type": "string", "const": "yaak-license:allow-check" }, + { + "description": "Enables the deactivate command without any pre-configured scope.", + "type": "string", + "const": "yaak-license:allow-deactivate" + }, { "description": "Denies the activate command without any pre-configured scope.", "type": "string", @@ -5582,6 +5587,11 @@ "type": "string", "const": "yaak-license:deny-check" }, + { + "description": "Denies the deactivate command without any pre-configured scope.", + "type": "string", + "const": "yaak-license:deny-deactivate" + }, { "description": "Default permissions for the plugin", "type": "string", diff --git a/src-tauri/gen/schemas/macOS-schema.json b/src-tauri/gen/schemas/macOS-schema.json index dc693cf11..66760a062 100644 --- a/src-tauri/gen/schemas/macOS-schema.json +++ b/src-tauri/gen/schemas/macOS-schema.json @@ -5572,6 +5572,11 @@ "type": "string", "const": "yaak-license:allow-check" }, + { + "description": "Enables the deactivate command without any pre-configured scope.", + "type": "string", + "const": "yaak-license:allow-deactivate" + }, { "description": "Denies the activate command without any pre-configured scope.", "type": "string", @@ -5582,6 +5587,11 @@ "type": "string", "const": "yaak-license:deny-check" }, + { + "description": "Denies the deactivate command without any pre-configured scope.", + "type": "string", + "const": "yaak-license:deny-deactivate" + }, { "description": "Default permissions for the plugin", "type": "string", diff --git a/src-tauri/yaak-license/bindings/license.ts b/src-tauri/yaak-license/bindings/license.ts index 0232d4249..9e64bec3c 100644 --- a/src-tauri/yaak-license/bindings/license.ts +++ b/src-tauri/yaak-license/bindings/license.ts @@ -8,4 +8,6 @@ export type ActivateLicenseResponsePayload = { activationId: string, }; export type CheckActivationResponsePayload = { active: boolean, }; +export type DeactivateLicenseRequestPayload = { licenseKey: string, appVersion: string, appPlatform: string, }; + export type LicenseCheckStatus = { "type": "personal_use", trial_ended: string, } | { "type": "commercial_use" } | { "type": "invalid_license" } | { "type": "trialing", end: string, }; diff --git a/src-tauri/yaak-license/build.rs b/src-tauri/yaak-license/build.rs index a6ac60bd1..6b08f5ff3 100644 --- a/src-tauri/yaak-license/build.rs +++ b/src-tauri/yaak-license/build.rs @@ -1,4 +1,4 @@ -const COMMANDS: &[&str] = &["activate", "check"]; +const COMMANDS: &[&str] = &["activate", "deactivate", "check"]; fn main() { tauri_plugin::Builder::new(COMMANDS).build(); diff --git a/src-tauri/yaak-license/index.ts b/src-tauri/yaak-license/index.ts index 42d82f587..66e6b0311 100644 --- a/src-tauri/yaak-license/index.ts +++ b/src-tauri/yaak-license/index.ts @@ -14,6 +14,12 @@ export function useLicense() { onSuccess: () => queryClient.invalidateQueries({ queryKey: CHECK_QUERY_KEY }), }); + const deactivate = useMutation({ + mutationKey: ['license.deactivate'], + mutationFn: () => invoke('plugin:yaak-license|deactivate'), + onSuccess: () => queryClient.invalidateQueries({ queryKey: CHECK_QUERY_KEY }), + }); + // Check the license again after a license is activated useEffect(() => { const unlisten = listen('license-activated', async () => { @@ -27,12 +33,14 @@ export function useLicense() { const CHECK_QUERY_KEY = ['license.check']; const check = useQuery({ refetchInterval: 1000 * 60 * 60 * 12, // Refetch every 12 hours + refetchOnWindowFocus: false, queryKey: CHECK_QUERY_KEY, queryFn: () => invoke('plugin:yaak-license|check'), }); return { activate, + deactivate, check, } as const; } diff --git a/src-tauri/yaak-license/permissions/autogenerated/commands/deactivate.toml b/src-tauri/yaak-license/permissions/autogenerated/commands/deactivate.toml new file mode 100644 index 000000000..035e8191e --- /dev/null +++ b/src-tauri/yaak-license/permissions/autogenerated/commands/deactivate.toml @@ -0,0 +1,13 @@ +# Automatically generated - DO NOT EDIT! + +"$schema" = "../../schemas/schema.json" + +[[permission]] +identifier = "allow-deactivate" +description = "Enables the deactivate command without any pre-configured scope." +commands.allow = ["deactivate"] + +[[permission]] +identifier = "deny-deactivate" +description = "Denies the deactivate command without any pre-configured scope." +commands.deny = ["deactivate"] diff --git a/src-tauri/yaak-license/permissions/autogenerated/reference.md b/src-tauri/yaak-license/permissions/autogenerated/reference.md index 48f872642..f6dead4ab 100644 --- a/src-tauri/yaak-license/permissions/autogenerated/reference.md +++ b/src-tauri/yaak-license/permissions/autogenerated/reference.md @@ -4,6 +4,7 @@ Default permissions for the plugin - `allow-check` - `allow-activate` +- `allow-deactivate` ## Permission Table @@ -63,6 +64,32 @@ Enables the check command without any pre-configured scope. Denies the check command without any pre-configured scope. + + + + + + +`yaak-license:allow-deactivate` + + + + +Enables the deactivate command without any pre-configured scope. + + + + + + + +`yaak-license:deny-deactivate` + + + + +Denies the deactivate command without any pre-configured scope. + diff --git a/src-tauri/yaak-license/permissions/default.toml b/src-tauri/yaak-license/permissions/default.toml index 4d304e82f..2ce8a2a3e 100644 --- a/src-tauri/yaak-license/permissions/default.toml +++ b/src-tauri/yaak-license/permissions/default.toml @@ -1,3 +1,3 @@ [default] description = "Default permissions for the plugin" -permissions = ["allow-check", "allow-activate"] +permissions = ["allow-check", "allow-activate", "allow-deactivate"] diff --git a/src-tauri/yaak-license/permissions/schemas/schema.json b/src-tauri/yaak-license/permissions/schemas/schema.json index 538b47463..3071b1109 100644 --- a/src-tauri/yaak-license/permissions/schemas/schema.json +++ b/src-tauri/yaak-license/permissions/schemas/schema.json @@ -314,6 +314,16 @@ "type": "string", "const": "deny-check" }, + { + "description": "Enables the deactivate command without any pre-configured scope.", + "type": "string", + "const": "allow-deactivate" + }, + { + "description": "Denies the deactivate command without any pre-configured scope.", + "type": "string", + "const": "deny-deactivate" + }, { "description": "Default permissions for the plugin", "type": "string", diff --git a/src-tauri/yaak-license/src/commands.rs b/src-tauri/yaak-license/src/commands.rs index 6893b3efe..15246dc77 100644 --- a/src-tauri/yaak-license/src/commands.rs +++ b/src-tauri/yaak-license/src/commands.rs @@ -1,5 +1,5 @@ use crate::errors::Result; -use crate::{activate_license, check_license, ActivateLicenseRequestPayload, LicenseCheckStatus}; +use crate::{activate_license, check_license, deactivate_license, get_activation_id, ActivateLicenseRequestPayload, CheckActivationRequestPayload, DeactivateLicenseRequestPayload, LicenseCheckStatus}; use log::{debug, info}; use std::string::ToString; use tauri::{command, AppHandle, Manager, Runtime, WebviewWindow}; @@ -7,7 +7,10 @@ use tauri::{command, AppHandle, Manager, Runtime, WebviewWindow}; #[command] pub async fn check(app_handle: AppHandle) -> Result { debug!("Checking license"); - check_license(&app_handle).await + check_license(&app_handle, CheckActivationRequestPayload{ + app_platform: get_os().to_string(), + app_version: app_handle.package_info().version.to_string(), + }).await } #[command] @@ -24,6 +27,19 @@ pub async fn activate(license_key: &str, window: WebviewWindow) - .await } +#[command] +pub async fn deactivate(window: WebviewWindow) -> Result<()> { + info!("Deactivating activation"); + deactivate_license( + &window, + DeactivateLicenseRequestPayload { + app_platform: get_os().to_string(), + app_version: window.app_handle().package_info().version.to_string(), + }, + ) + .await +} + fn get_os() -> &'static str { if cfg!(target_os = "windows") { "windows" diff --git a/src-tauri/yaak-license/src/lib.rs b/src-tauri/yaak-license/src/lib.rs index e12711a2b..254086c7d 100644 --- a/src-tauri/yaak-license/src/lib.rs +++ b/src-tauri/yaak-license/src/lib.rs @@ -8,9 +8,11 @@ mod commands; mod errors; mod license; -use crate::commands::{activate, check}; +use crate::commands::{activate, check, deactivate}; pub use license::*; pub fn init() -> TauriPlugin { - Builder::new("yaak-license").invoke_handler(generate_handler![check, activate]).build() + Builder::new("yaak-license") + .invoke_handler(generate_handler![check, activate, deactivate]) + .build() } diff --git a/src-tauri/yaak-license/src/license.rs b/src-tauri/yaak-license/src/license.rs index 2a84043dc..db58b03c5 100644 --- a/src-tauri/yaak-license/src/license.rs +++ b/src-tauri/yaak-license/src/license.rs @@ -5,7 +5,7 @@ use log::{debug, info, warn}; use serde::{Deserialize, Serialize}; use std::ops::Add; use std::time::Duration; -use tauri::{is_dev, AppHandle, Emitter, Runtime, WebviewWindow}; +use tauri::{is_dev, AppHandle, Emitter, Manager, Runtime, WebviewWindow}; use ts_rs::TS; use yaak_models::queries::UpdateSource; @@ -17,7 +17,8 @@ const TRIAL_SECONDS: u64 = 3600 * 24 * 30; #[serde(rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] pub struct CheckActivationRequestPayload { - pub activation_id: String, + pub app_version: String, + pub app_platform: String, } #[derive(Debug, Clone, Serialize, Deserialize, TS)] @@ -36,6 +37,14 @@ pub struct ActivateLicenseRequestPayload { pub app_platform: String, } +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export, export_to = "license.ts")] +pub struct DeactivateLicenseRequestPayload { + pub app_version: String, + pub app_platform: String, +} + #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "camelCase")] #[ts(export, export_to = "license.ts")] @@ -56,7 +65,7 @@ pub async fn activate_license( p: ActivateLicenseRequestPayload, ) -> Result<()> { let client = reqwest::Client::new(); - let response = client.post(build_url("/activate")).json(&p).send().await?; + let response = client.post(build_url("/licenses/activate")).json(&p).send().await?; if response.status().is_client_error() { let body: APIErrorResponsePayload = response.json().await?; @@ -86,6 +95,44 @@ pub async fn activate_license( Ok(()) } + +pub async fn deactivate_license( + window: &WebviewWindow, + p: DeactivateLicenseRequestPayload, +) -> Result<()> { + let activation_id = get_activation_id(window).await; + + let client = reqwest::Client::new(); + let path = format!("/licenses/activations/{}/deactivate", activation_id); + let response = client.post(build_url(&path)).json(&p).send().await?; + + if response.status().is_client_error() { + let body: APIErrorResponsePayload = response.json().await?; + return Err(ClientError { + message: body.message, + error: body.error, + }); + } + + if response.status().is_server_error() { + return Err(ServerError); + } + + yaak_models::queries::delete_key_value( + window, + KV_ACTIVATION_ID_KEY, + KV_NAMESPACE, + &UpdateSource::Window, + ) + .await; + + if let Err(e) = window.emit("license-deactivated", true) { + warn!("Failed to emit deactivate-license event: {}", e); + } + + Ok(()) +} + #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "snake_case", tag = "type")] #[ts(export, export_to = "license.ts")] @@ -96,15 +143,8 @@ pub enum LicenseCheckStatus { Trialing { end: NaiveDateTime }, } -pub async fn check_license(app_handle: &AppHandle) -> Result { - let activation_id = yaak_models::queries::get_key_value_string( - app_handle, - KV_ACTIVATION_ID_KEY, - KV_NAMESPACE, - "", - ) - .await; - +pub async fn check_license(app_handle: &AppHandle, payload: CheckActivationRequestPayload) -> Result { + let activation_id = get_activation_id(app_handle).await; let settings = yaak_models::queries::get_or_create_settings(app_handle).await; let trial_end = settings.created_at.add(Duration::from_secs(TRIAL_SECONDS)); @@ -122,10 +162,8 @@ pub async fn check_license(app_handle: &AppHandle) -> Result(app_handle: &AppHandle) -> Result String { if is_dev() { - format!("http://localhost:9444/licenses{path}") + format!("http://localhost:9444{path}") } else { - format!("https://license.yaak.app/licenses{path}") + format!("https://license.yaak.app{path}") } } + +pub async fn get_activation_id(mgr: &impl Manager) -> String { + yaak_models::queries::get_key_value_string(mgr, KV_ACTIVATION_ID_KEY, KV_NAMESPACE, "") + .await +} diff --git a/src-tauri/yaak-models/src/queries.rs b/src-tauri/yaak-models/src/queries.rs index 5e3cb68ea..a6d268490 100644 --- a/src-tauri/yaak-models/src/queries.rs +++ b/src-tauri/yaak-models/src/queries.rs @@ -134,6 +134,31 @@ pub async fn set_key_value_raw( (m, existing.is_none()) } +pub async fn delete_key_value( + w: &WebviewWindow, + namespace: &str, + key: &str, + update_source: &UpdateSource, +) { + let kv = match get_key_value_raw(w, namespace, key).await { + None => return, + Some(m) => m, + }; + + let dbm = &*w.state::(); + let db = dbm.0.lock().await.get().unwrap(); + let (sql, params) = Query::delete() + .from_table(KeyValueIden::Table) + .cond_where( + Cond::all() + .add(Expr::col(KeyValueIden::Namespace).eq(namespace)) + .add(Expr::col(KeyValueIden::Key).eq(key)), + ) + .build_rusqlite(SqliteQueryBuilder); + db.execute(sql.as_str(), &*params.as_params()).expect("Failed to delete PluginKeyValue"); + emit_deleted_model(w, &AnyModel::KeyValue(kv.to_owned()), update_source); +} + pub async fn list_key_values_raw(mgr: &impl Manager) -> Result> { let dbm = &*mgr.state::(); let db = dbm.0.lock().await.get().unwrap(); diff --git a/src-web/components/LicenseBadge.tsx b/src-web/components/LicenseBadge.tsx index bd3e250c7..28df195ba 100644 --- a/src-web/components/LicenseBadge.tsx +++ b/src-web/components/LicenseBadge.tsx @@ -27,13 +27,26 @@ const details: Record< commercial_use: null, invalid_license: { label: 'License Error', color: 'danger' }, personal_use: { label: 'Personal Use', color: 'success' }, - trialing: { label: 'Active Trial', color: 'success' }, + trialing: { label: 'Personal Use', color: 'success' }, }; export function LicenseBadge() { const { check } = useLicense(); const [licenseDetails, setLicenseDetails] = useLicenseConfirmation(); + if (check.error) { + return ( + { + openSettings.mutate(SettingsTab.License); + }} + > + License Error + + ); + } + // Hasn't loaded yet if (licenseDetails == null || check.data == null) { return null; @@ -56,10 +69,7 @@ export function LicenseBadge() { } return ( - + ); } + +function LicenseBadgeButton({ ...props }: ButtonProps) { + return )} @@ -289,6 +285,7 @@ type PairEditorRowProps = { } & Pick< PairEditorProps, | 'allowFileValues' + | 'allowMultilineValues' | 'forceUpdateKey' | 'nameAutocomplete' | 'nameAutocompleteVariables' @@ -304,6 +301,7 @@ type PairEditorRowProps = { function PairEditorRow({ allowFileValues, + allowMultilineValues, className, forceFocusNamePairId, forceFocusValuePairId, @@ -330,7 +328,6 @@ function PairEditorRow({ const ref = useRef(null); const nameInputRef = useRef(null); const valueInputRef = useRef(null); - const valueLanguage = languageFromContentType(pair.contentType ?? null); useEffect(() => { if (forceFocusNamePairId === pair.id) { @@ -347,17 +344,6 @@ function PairEditorRow({ const handleFocus = useCallback(() => onFocus?.(pair), [onFocus, pair]); const handleDelete = useCallback(() => onDelete?.(pair, false), [onDelete, pair]); - const deleteItems = useMemo( - (): DropdownItem[] => [ - { - label: 'Delete', - onSelect: handleDelete, - color: 'danger', - }, - ], - [handleDelete], - ); - const handleChangeEnabled = useMemo( () => (enabled: boolean) => onChange({ ...pair, enabled }), [onChange, pair], @@ -396,11 +382,27 @@ function PairEditorRow({ hide={hide} onChange={handleChangeValueText} defaultValue={pair.value} - language={valueLanguage} + contentType={pair.contentType ?? null} /> ), }), - [handleChangeValueText, pair.name, pair.value, valueLanguage], + [handleChangeValueText, pair.contentType, pair.name, pair.value], + ); + + const defaultItems = useMemo( + (): DropdownItem[] => [ + { + label: 'Edit Multi-line', + onSelect: handleEditMultiLineValue, + hidden: !allowMultilineValues, + }, + { + label: 'Delete', + onSelect: handleDelete, + color: 'danger', + }, + ], + [allowMultilineValues, handleDelete, handleEditMultiLineValue], ); const [, connectDrop] = useDrop( @@ -524,8 +526,9 @@ function PairEditorRow({ size="sm" onClick={handleEditMultiLineValue} title={pair.value} + className="text-xs font-mono" > - Edit {formatSize(pair.value.length)} + {pair.value.split('\n').join(' ')} ) : ( ) : ( - + , + color: 'danger', }, ], [editMultiLine, onChangeContentType, onChangeFile, onDelete, pair.contentType, pair.isFile], @@ -673,16 +676,17 @@ function isPairEmpty(pair: Pair): boolean { function MultilineEditDialog({ defaultValue, - language, + contentType, onChange, hide, }: { defaultValue: string; - language: EditorProps['language']; + contentType: string | null; onChange: (value: string) => void; hide: () => void; }) { const [value, setValue] = useState(defaultValue); + const language = languageFromContentType(contentType, value); return (
@@ -195,7 +198,7 @@ function FormInputs>({ inputs={input.inputs} setDataAttr={setDataAttr} stateKey={stateKey} - useTemplating={useTemplating} + autocompleteFunctions={autocompleteFunctions || false} autocompleteVariables={autocompleteVariables} /> @@ -212,14 +215,14 @@ function TextArg({ arg, onChange, value, - useTemplating, + autocompleteFunctions, autocompleteVariables, stateKey, }: { arg: FormInputText; value: string; onChange: (v: string) => void; - useTemplating: boolean; + autocompleteFunctions: boolean; autocompleteVariables: boolean; stateKey: string; }) { @@ -237,7 +240,7 @@ function TextArg({ hideLabel={arg.label == null} placeholder={arg.placeholder ?? undefined} autocomplete={arg.completionOptions ? { options: arg.completionOptions } : undefined} - useTemplating={useTemplating} + autocompleteFunctions={autocompleteFunctions} autocompleteVariables={autocompleteVariables} stateKey={stateKey} forceUpdateKey={stateKey} @@ -249,14 +252,14 @@ function EditorArg({ arg, onChange, value, - useTemplating, + autocompleteFunctions, autocompleteVariables, stateKey, }: { arg: FormInputEditor; value: string; onChange: (v: string) => void; - useTemplating: boolean; + autocompleteFunctions: boolean; autocompleteVariables: boolean; stateKey: string; }) { @@ -290,7 +293,7 @@ function EditorArg({ heightMode="auto" defaultValue={value === DYNAMIC_FORM_NULL_ARG ? arg.defaultValue : value} placeholder={arg.placeholder ?? undefined} - useTemplating={useTemplating} + autocompleteFunctions={autocompleteFunctions} autocompleteVariables={autocompleteVariables} stateKey={stateKey} forceUpdateKey={forceUpdateKey} diff --git a/src-web/components/EnvironmentEditDialog.tsx b/src-web/components/EnvironmentEditDialog.tsx index a0630b05b..1a7f40921 100644 --- a/src-web/components/EnvironmentEditDialog.tsx +++ b/src-web/components/EnvironmentEditDialog.tsx @@ -116,7 +116,7 @@ export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) { }; const EnvironmentEditor = function ({ - environment, + environment: activeEnvironment, className, }: { environment: Environment; @@ -127,8 +127,8 @@ const EnvironmentEditor = function ({ key: 'environmentValueVisibility', fallback: true, }); - const { subEnvironments } = useEnvironments(); - const updateEnvironment = useUpdateEnvironment(environment?.id ?? null); + const { allEnvironments } = useEnvironments(); + const updateEnvironment = useUpdateEnvironment(activeEnvironment?.id ?? null); const handleChange = useCallback( (variables) => updateEnvironment.mutate({ variables }), [updateEnvironment], @@ -136,26 +136,28 @@ const EnvironmentEditor = function ({ // Gather a list of env names from other environments, to help the user get them aligned const nameAutocomplete = useMemo(() => { - const allVariableNames = - environment == null - ? [] // Nothing to autocomplete if we're in the base environment - : subEnvironments - .filter((e) => e.environmentId != null) - .flatMap((e) => e.variables.map((v) => v.name)); + const options: GenericCompletionOption[] = []; + const isBaseEnv = activeEnvironment.environmentId == null; + if (isBaseEnv) { + return { options }; + } - // Filter out empty strings and variables that already exist - const variableNames = allVariableNames.filter( - (name) => name != '' && !environment.variables.find((v) => v.name === name), - ); - const uniqueVariableNames = [...new Set(variableNames)]; - const options = uniqueVariableNames.map( - (name): GenericCompletionOption => ({ + const allVariables = allEnvironments.flatMap((e) => e?.variables); + const allVariableNames = new Set(allVariables.map((v) => v?.name)); + for (const name of allVariableNames) { + const containingEnvs = allEnvironments.filter((e) => + e.variables.some((v) => v.name === name), + ); + const isAlreadyInActive = containingEnvs.find((e) => e.id === activeEnvironment.id); + if (isAlreadyInActive) continue; + options.push({ label: name, type: 'constant', - }), - ); + detail: containingEnvs.map((e) => e.name).join(', '), + }); + } return { options }; - }, [subEnvironments, environment]); + }, [activeEnvironment.environmentId, activeEnvironment.id, allEnvironments]); const validateName = useCallback((name: string) => { // Empty just means the variable doesn't have a name yet, and is unusable @@ -167,7 +169,7 @@ const EnvironmentEditor = function ({ -
{environment?.name}
+
{activeEnvironment?.name}
diff --git a/src-web/components/FormMultipartEditor.tsx b/src-web/components/FormMultipartEditor.tsx index 689d4027e..bc6aa97be 100644 --- a/src-web/components/FormMultipartEditor.tsx +++ b/src-web/components/FormMultipartEditor.tsx @@ -40,8 +40,10 @@ export function FormMultipartEditor({ request, forceUpdateKey, onChange }: Props return ( diff --git a/src-web/components/GrpcEditor.tsx b/src-web/components/GrpcEditor.tsx index 80cca1924..f2c8d432b 100644 --- a/src-web/components/GrpcEditor.tsx +++ b/src-web/components/GrpcEditor.tsx @@ -181,8 +181,8 @@ export function GrpcEditor({
diff --git a/src-web/components/WebsocketRequestPane.tsx b/src-web/components/WebsocketRequestPane.tsx index 58acdd630..bd26e5a77 100644 --- a/src-web/components/WebsocketRequestPane.tsx +++ b/src-web/components/WebsocketRequestPane.tsx @@ -301,7 +301,7 @@ export function WebsocketRequestPane({ style, fullHeight, className, activeReque = { }; export interface EditorProps { - id?: string; - readOnly?: boolean; - disabled?: boolean; - type?: 'text' | 'password'; - className?: string; - heightMode?: 'auto' | 'full'; - language?: EditorLanguage | 'pairs' | 'url'; - forceUpdateKey?: string | number; + actions?: ReactNode; autoFocus?: boolean; autoSelect?: boolean; + autocomplete?: GenericCompletionConfig; + autocompleteFunctions?: boolean; + autocompleteVariables?: boolean; + className?: string; defaultValue?: string | null; - placeholder?: string; - tooltipContainer?: HTMLElement; - useTemplating?: boolean; + disableTabIndent?: boolean; + disabled?: boolean; + extraExtensions?: Extension[]; + forceUpdateKey?: string | number; + format?: (v: string) => Promise; + heightMode?: 'auto' | 'full'; + hideGutter?: boolean; + id?: string; + language?: EditorLanguage | 'pairs' | 'url'; + onBlur?: () => void; onChange?: (value: string) => void; - onPaste?: (value: string) => void; - onPasteOverwrite?: (e: ClipboardEvent, value: string) => void; onFocus?: () => void; - onBlur?: () => void; onKeyDown?: (e: KeyboardEvent) => void; + onPaste?: (value: string) => void; + onPasteOverwrite?: (e: ClipboardEvent, value: string) => void; + placeholder?: string; + readOnly?: boolean; singleLine?: boolean; - wrapLines?: boolean; - disableTabIndent?: boolean; - format?: (v: string) => Promise; - autocomplete?: GenericCompletionConfig; - autocompleteVariables?: boolean; - extraExtensions?: Extension[]; - actions?: ReactNode; - hideGutter?: boolean; stateKey: string | null; + tooltipContainer?: HTMLElement; + type?: 'text' | 'password'; + wrapLines?: boolean; } const stateFields = { history: historyField, folds: foldState }; @@ -94,34 +94,34 @@ const emptyExtension: Extension = []; export const Editor = forwardRef(function Editor( { - readOnly, - type, - heightMode, - language, + actions, autoFocus, autoSelect, - placeholder, - useTemplating, + autocomplete, + autocompleteFunctions, + autocompleteVariables, + className, defaultValue, + disableTabIndent, + disabled, + extraExtensions, forceUpdateKey, + format, + heightMode, + hideGutter, + language, + onBlur, onChange, - onPaste, - onPasteOverwrite, onFocus, - onBlur, onKeyDown, - className, - disabled, + onPaste, + onPasteOverwrite, + placeholder, + readOnly, singleLine, - format, - autocomplete, - extraExtensions, - autocompleteVariables, - actions, - wrapLines, - disableTabIndent, - hideGutter, stateKey, + type, + wrapLines, }: EditorProps, ref, ) { @@ -129,6 +129,7 @@ export const Editor = forwardRef(function E const allEnvironmentVariables = useActiveEnvironmentVariables(); const environmentVariables = autocompleteVariables ? allEnvironmentVariables : emptyVariables; + const useTemplating = !!(autocompleteFunctions || autocompleteVariables || autocomplete); if (settings && wrapLines === undefined) { wrapLines = settings.editorSoftWrap; @@ -340,16 +341,19 @@ export const Editor = forwardRef(function E [focusParamValue], ); - const completionOptions = useTemplateFunctionCompletionOptions(onClickFunction); + const completionOptions = useTemplateFunctionCompletionOptions( + onClickFunction, + !!autocompleteFunctions, + ); // Update the language extension when the language changes useEffect(() => { if (cm.current === null) return; const { view, languageCompartment } = cm.current; const ext = getLanguageExtension({ + useTemplating, language, environmentVariables, - useTemplating, autocomplete, completionOptions, onClickVariable, @@ -360,13 +364,13 @@ export const Editor = forwardRef(function E }, [ language, autocomplete, - useTemplating, environmentVariables, onClickFunction, onClickVariable, onClickMissingVariable, onClickPathParameter, completionOptions, + useTemplating, ]); // Initialize the editor when ref mounts @@ -381,8 +385,8 @@ export const Editor = forwardRef(function E try { const languageCompartment = new Compartment(); const langExt = getLanguageExtension({ - language, useTemplating, + language, completionOptions, autocomplete, environmentVariables, diff --git a/src-web/components/core/Editor/extensions.ts b/src-web/components/core/Editor/extensions.ts index 056fdd1e4..092b432b4 100644 --- a/src-web/components/core/Editor/extensions.ts +++ b/src-web/components/core/Editor/extensions.ts @@ -91,8 +91,8 @@ const syntaxExtensions: Record, LanguageSup const closeBracketsFor: (keyof typeof syntaxExtensions)[] = ['json', 'javascript', 'graphql']; export function getLanguageExtension({ + useTemplating, language = 'text', - useTemplating = false, environmentVariables, autocomplete, onClickVariable, @@ -100,12 +100,13 @@ export function getLanguageExtension({ onClickPathParameter, completionOptions, }: { + useTemplating: boolean; environmentVariables: EnvironmentVariable[]; onClickVariable: (option: EnvironmentVariable, tagValue: string, startPos: number) => void; onClickMissingVariable: (name: string, tagValue: string, startPos: number) => void; onClickPathParameter: (name: string) => void; completionOptions: TwigCompletionOption[]; -} & Pick) { +} & Pick) { const extraExtensions: Extension[] = []; if (language === 'url') { diff --git a/src-web/components/core/Input.tsx b/src-web/components/core/Input.tsx index fc92560dc..ab5c7cb3c 100644 --- a/src-web/components/core/Input.tsx +++ b/src-web/components/core/Input.tsx @@ -13,13 +13,13 @@ import { HStack } from './Stacks'; export type InputProps = Pick< EditorProps, | 'language' - | 'useTemplating' | 'autocomplete' | 'forceUpdateKey' | 'disabled' | 'autoFocus' | 'autoSelect' | 'autocompleteVariables' + | 'autocompleteFunctions' | 'onKeyDown' | 'readOnly' > & { diff --git a/src-web/components/core/PairEditor.tsx b/src-web/components/core/PairEditor.tsx index 1fb820784..6f678a77a 100644 --- a/src-web/components/core/PairEditor.tsx +++ b/src-web/components/core/PairEditor.tsx @@ -43,6 +43,7 @@ export type PairEditorProps = { className?: string; forceUpdateKey?: string; nameAutocomplete?: GenericCompletionConfig; + nameAutocompleteFunctions?: boolean; nameAutocompleteVariables?: boolean; namePlaceholder?: string; nameValidate?: InputProps['validate']; @@ -51,6 +52,7 @@ export type PairEditorProps = { pairs: Pair[]; stateKey: InputProps['stateKey']; valueAutocomplete?: (name: string) => GenericCompletionConfig | undefined; + valueAutocompleteFunctions?: boolean; valueAutocompleteVariables?: boolean; valuePlaceholder?: string; valueType?: 'text' | 'password'; @@ -82,6 +84,7 @@ export const PairEditor = forwardRef(function Pa className, forceUpdateKey, nameAutocomplete, + nameAutocompleteFunctions, nameAutocompleteVariables, namePlaceholder, nameValidate, @@ -89,6 +92,7 @@ export const PairEditor = forwardRef(function Pa onChange, pairs: originalPairs, valueAutocomplete, + valueAutocompleteFunctions, valueAutocompleteVariables, valuePlaceholder, valueType, @@ -237,6 +241,7 @@ export const PairEditor = forwardRef(function Pa index={i} isLast={isLast} nameAutocomplete={nameAutocomplete} + nameAutocompleteFunctions={nameAutocompleteFunctions} nameAutocompleteVariables={nameAutocompleteVariables} namePlaceholder={namePlaceholder} nameValidate={nameValidate} @@ -248,6 +253,7 @@ export const PairEditor = forwardRef(function Pa pair={p} stateKey={stateKey} valueAutocomplete={valueAutocomplete} + valueAutocompleteFunctions={valueAutocompleteFunctions} valueAutocompleteVariables={valueAutocompleteVariables} valuePlaceholder={valuePlaceholder} valueType={valueType} @@ -291,8 +297,10 @@ type PairEditorRowProps = { | 'nameAutocompleteVariables' | 'namePlaceholder' | 'nameValidate' + | 'nameAutocompleteFunctions' | 'stateKey' | 'valueAutocomplete' + | 'valueAutocompleteFunctions' | 'valueAutocompleteVariables' | 'valuePlaceholder' | 'valueType' @@ -309,9 +317,10 @@ function PairEditorRow({ index, isLast, nameAutocomplete, - nameAutocompleteVariables, namePlaceholder, nameValidate, + nameAutocompleteFunctions, + nameAutocompleteVariables, onChange, onDelete, onEnd, @@ -320,6 +329,7 @@ function PairEditorRow({ pair, stateKey, valueAutocomplete, + valueAutocompleteFunctions, valueAutocompleteVariables, valuePlaceholder, valueType, @@ -486,7 +496,6 @@ function PairEditorRow({ )}
@@ -534,7 +544,6 @@ function PairEditorRow({ )} @@ -695,7 +705,7 @@ function MultilineEditDialog({ language={language} onChange={setValue} stateKey={null} - useTemplating + autocompleteFunctions autocompleteVariables />
diff --git a/src-web/hooks/useTemplateFunctions.ts b/src-web/hooks/useTemplateFunctions.ts index b57f5afdb..1cbb1db5d 100644 --- a/src-web/hooks/useTemplateFunctions.ts +++ b/src-web/hooks/useTemplateFunctions.ts @@ -11,9 +11,13 @@ const templateFunctionsAtom = atom([]); export function useTemplateFunctionCompletionOptions( onClick: (fn: TemplateFunction, ragTag: string, pos: number) => void, + enabled: boolean, ) { const templateFunctions = useAtomValue(templateFunctionsAtom); return useMemo(() => { + if (!enabled) { + return []; + } return ( templateFunctions.map((fn) => { const NUM_ARGS = 2; @@ -35,7 +39,7 @@ export function useTemplateFunctionCompletionOptions( }; }) ?? [] ); - }, [onClick, templateFunctions]); + }, [enabled, onClick, templateFunctions]); } export function useSubscribeTemplateFunctions() { From cb773babe1716e11e549345625f9bde5c5323d3f Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 18 Mar 2025 12:49:19 -0700 Subject: [PATCH 099/996] Nested template functions (#186) --- DEVELOPMENT.md | 7 + src-tauri/Cargo.lock | 1 + src-tauri/src/lib.rs | 4 +- src-tauri/yaak-templates/Cargo.toml | 5 +- src-tauri/yaak-templates/src/parser.rs | 245 +++++++++++++----- src-tauri/yaak-templates/src/renderer.rs | 108 +++++--- src-web/components/TemplateFunctionDialog.tsx | 66 ++++- src-web/components/core/Editor/Editor.tsx | 2 +- src-web/components/core/Icon.tsx | 1 + 9 files changed, 321 insertions(+), 118 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 508eeabac..e4bedc06f 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -60,3 +60,10 @@ Run the app to apply the migrations. If nothing happens, try `cargo clean` and run the app again. _Note: Development builds use a separate database location from production builds._ + +## Lezer Grammer Generation + +```sh +# Example +lezer-generator components/core/Editor//.grammar > components/core/Editor//.ts +``` diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 6e55d2c85..83c90a4e9 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -7838,6 +7838,7 @@ dependencies = [ name = "yaak-templates" version = "0.1.0" dependencies = [ + "base64 0.22.1", "log", "serde", "serde_json", diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 44e9cfffd..4eb486afe 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -114,8 +114,8 @@ async fn cmd_metadata(app_handle: AppHandle) -> Result { } #[tauri::command] -async fn cmd_parse_template(template: &str) -> Result { - Ok(Parser::new(template).parse()) +async fn cmd_parse_template(template: &str) -> YaakResult { + Ok(Parser::new(template).parse()?) } #[tauri::command] diff --git a/src-tauri/yaak-templates/Cargo.toml b/src-tauri/yaak-templates/Cargo.toml index e6dae6eca..e960475a7 100644 --- a/src-tauri/yaak-templates/Cargo.toml +++ b/src-tauri/yaak-templates/Cargo.toml @@ -5,9 +5,10 @@ edition = "2021" publish = false [dependencies] +base64 = "0.22.1" +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } log = "0.4.22" -serde = { version = "1.0.208", features = ["derive"] } -serde_json = "1.0.132" thiserror = { workspace = true } tokio = { version = "1.39.3", features = ["macros", "rt"] } ts-rs = { version = "10.0.0" } diff --git a/src-tauri/yaak-templates/src/parser.rs b/src-tauri/yaak-templates/src/parser.rs index f4d6791c3..b0f009ee9 100644 --- a/src-tauri/yaak-templates/src/parser.rs +++ b/src-tauri/yaak-templates/src/parser.rs @@ -1,3 +1,7 @@ +use crate::error::Error::RenderError; +use crate::error::Result; +use base64::prelude::BASE64_URL_SAFE_NO_PAD; +use base64::Engine; use serde::{Deserialize, Serialize}; use std::fmt::Display; use ts_rs::TS; @@ -43,7 +47,13 @@ pub enum Val { impl Display for Val { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let str = match self { - Val::Str { text } => format!("'{}'", text.to_string().replace("'", "\'")), + Val::Str { text } => { + if text.chars().all(|c| c.is_alphanumeric() || c == ' ' || c == '_' || c == '_') { + format!("'{}'", text) + } else { + format!("b64'{}'", BASE64_URL_SAFE_NO_PAD.encode(text)) + } + } Val::Var { name } => name.to_string(), Val::Bool { value } => value.to_string(), Val::Fn { name, args } => { @@ -108,13 +118,13 @@ impl Parser { } } - pub fn parse(&mut self) -> Tokens { + pub fn parse(&mut self) -> Result { let start_pos = self.pos; while self.pos < self.chars.len() { if self.match_str("${[") { let start_curr = self.pos; - if let Some(t) = self.parse_tag() { + if let Some(t) = self.parse_tag()? { self.push_token(t); } else { self.pos = start_curr; @@ -131,29 +141,29 @@ impl Parser { } self.push_token(Token::Eof); - Tokens { + Ok(Tokens { tokens: self.tokens.clone(), - } + }) } - fn parse_tag(&mut self) -> Option { + fn parse_tag(&mut self) -> Result> { // Parse up to first identifier // ${[ my_var... self.skip_whitespace(); - let val = match self.parse_value() { + let val = match self.parse_value()? { Some(v) => v, - None => return None, + None => return Ok(None), }; // Parse to closing tag // ${[ my_var(a, b, c) ]} self.skip_whitespace(); if !self.match_str("]}") { - return None; + return Ok(None); } - Some(Token::Tag { val }) + Ok(Some(Token::Tag { val })) } #[allow(dead_code)] @@ -167,9 +177,11 @@ impl Parser { ); } - fn parse_value(&mut self) -> Option { - if let Some((name, args)) = self.parse_fn() { + fn parse_value(&mut self) -> Result> { + let v = if let Some((name, args)) = self.parse_fn()? { Some(Val::Fn { name, args }) + } else if let Some(v) = self.parse_string()? { + Some(Val::Str { text: v }) } else if let Some(v) = self.parse_ident() { if v == "null" { Some(Val::Null) @@ -180,38 +192,38 @@ impl Parser { } else { Some(Val::Var { name: v }) } - } else if let Some(v) = self.parse_string() { - Some(Val::Str { text: v }) } else { None - } + }; + + Ok(v) } - fn parse_fn(&mut self) -> Option<(String, Vec)> { + fn parse_fn(&mut self) -> Result)>> { let start_pos = self.pos; let name = match self.parse_fn_name() { Some(v) => v, None => { self.pos = start_pos; - return None; + return Ok(None); } }; - let args = match self.parse_fn_args() { + let args = match self.parse_fn_args()? { Some(args) => args, None => { self.pos = start_pos; - return None; + return Ok(None); } }; - Some((name, args)) + Ok(Some((name, args))) } - fn parse_fn_args(&mut self) -> Option> { + fn parse_fn_args(&mut self) -> Result>> { if !self.match_str("(") { - return None; + return Ok(None); } let start_pos = self.pos; @@ -221,7 +233,7 @@ impl Parser { // Fn closed immediately self.skip_whitespace(); if self.match_str(")") { - return Some(args); + return Ok(Some(args)); } while self.pos < self.chars.len() { @@ -231,7 +243,7 @@ impl Parser { self.skip_whitespace(); self.match_str("="); self.skip_whitespace(); - let value = self.parse_value(); + let value = self.parse_value()?; self.skip_whitespace(); if let (Some(name), Some(value)) = (name.clone(), value.clone()) { @@ -239,7 +251,7 @@ impl Parser { } else { // Didn't find valid thing, so return self.pos = start_pos; - return None; + return Ok(None); } if self.match_str(")") { @@ -251,7 +263,7 @@ impl Parser { // If we don't find a comma, that's bad if !args.is_empty() && !self.match_str(",") { self.pos = start_pos; - return None; + return Ok(None); } if start_pos == self.pos { @@ -259,7 +271,7 @@ impl Parser { } } - Some(args) + Ok(Some(args)) } fn parse_ident(&mut self) -> Option { @@ -319,12 +331,17 @@ impl Parser { Some(text) } - fn parse_string(&mut self) -> Option { + fn parse_string(&mut self) -> Result> { let start_pos = self.pos; let mut text = String::new(); - if !self.match_str("'") { - return None; + let mut is_b64 = false; + if self.match_str("b64'") { + is_b64 = true; + } else if self.match_str("'") { + // Nothing + } else { + return Ok(None); } let mut found_closing = false; @@ -350,10 +367,21 @@ impl Parser { if !found_closing { self.pos = start_pos; - return None; + return Ok(None); } - Some(text) + let final_text = if is_b64 { + let decoded = BASE64_URL_SAFE_NO_PAD + .decode(text.clone()) + .map_err(|_| RenderError(format!("Failed to decode string {text}")))?; + let decoded = String::from_utf8(decoded) + .map_err(|_| RenderError(format!("Failed to decode utf8 string {text}")))?; + decoded + } else { + text + }; + + Ok(Some(final_text)) } fn skip_whitespace(&mut self) { @@ -410,14 +438,15 @@ impl Parser { #[cfg(test)] mod tests { + use crate::error::Result; use crate::Val::Null; use crate::*; #[test] - fn var_simple() { + fn var_simple() -> Result<()> { let mut p = Parser::new("${[ foo ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Var { name: "foo".into() } @@ -425,13 +454,14 @@ mod tests { Token::Eof ] ); + Ok(()) } #[test] - fn var_dashes() { + fn var_dashes() -> Result<()> { let mut p = Parser::new("${[ a-b ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Var { name: "a-b".into() } @@ -439,13 +469,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn var_underscores() { + fn var_underscores() -> Result<()> { let mut p = Parser::new("${[ a_b ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Var { name: "a_b".into() } @@ -453,13 +485,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn var_prefixes() { + fn var_prefixes() -> Result<()> { let mut p = Parser::new("${[ -a ]}${[ 0a ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Raw { // Shouldn't be parsed, because they're invalid @@ -468,13 +502,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn var_underscore_prefix() { + fn var_underscore_prefix() -> Result<()> { let mut p = Parser::new("${[ _a ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Var { name: "_a".into() } @@ -482,13 +518,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn var_boolean() { + fn var_boolean() -> Result<()> { let mut p = Parser::new("${[ true ]}${[ false ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Bool { value: true }, @@ -499,13 +537,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn var_multiple_names_invalid() { + fn var_multiple_names_invalid() -> Result<()> { let mut p = Parser::new("${[ foo bar ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Raw { text: "${[ foo bar ]}".into() @@ -513,13 +553,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn tag_string() { + fn tag_string() -> Result<()> { let mut p = Parser::new(r#"${[ 'foo \'bar\' baz' ]}"#); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Str { @@ -529,13 +571,33 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn var_surrounded() { + fn tag_b64_string() -> Result<()> { + let mut p = Parser::new(r#"${[ b64'Zm9vICdiYXInIGJheg' ]}"#); + assert_eq!( + p.parse()?.tokens, + vec![ + Token::Tag { + val: Val::Str { + text: r#"foo 'bar' baz"#.into() + } + }, + Token::Eof + ] + ); + + Ok(()) + } + + #[test] + fn var_surrounded() -> Result<()> { let mut p = Parser::new("Hello ${[ foo ]}!"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Raw { text: "Hello ".to_string() @@ -549,13 +611,15 @@ mod tests { Token::Eof, ] ); + + Ok(()) } #[test] - fn fn_simple() { + fn fn_simple() -> Result<()> { let mut p = Parser::new("${[ foo() ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Fn { @@ -566,13 +630,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn fn_dot_name() { + fn fn_dot_name() -> Result<()> { let mut p = Parser::new("${[ foo.bar.baz() ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Fn { @@ -583,13 +649,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn fn_ident_arg() { + fn fn_ident_arg() -> Result<()> { let mut p = Parser::new("${[ foo(a=bar) ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Fn { @@ -603,13 +671,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn fn_ident_args() { + fn fn_ident_args() -> Result<()> { let mut p = Parser::new("${[ foo(a=bar,b = baz, c =qux ) ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Fn { @@ -633,13 +703,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn fn_mixed_args() { + fn fn_mixed_args() -> Result<()> { let mut p = Parser::new(r#"${[ foo(aaa=bar,bb='baz \'hi\'', c=qux, z=true ) ]}"#); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Fn { @@ -669,13 +741,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn fn_nested() { + fn fn_nested() -> Result<()> { let mut p = Parser::new("${[ foo(b=bar()) ]}"); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Fn { @@ -692,13 +766,15 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn fn_nested_args() { + fn fn_nested_args() -> Result<()> { let mut p = Parser::new(r#"${[ outer(a=inner(a=foo, b='i'), c='o') ]}"#); assert_eq!( - p.parse().tokens, + p.parse()?.tokens, vec![ Token::Tag { val: Val::Fn { @@ -730,10 +806,12 @@ mod tests { Token::Eof ] ); + + Ok(()) } #[test] - fn token_display_var() { + fn token_display_var() -> Result<()> { assert_eq!( Val::Var { name: "foo".to_string() @@ -741,21 +819,38 @@ mod tests { .to_string(), "foo" ); + + Ok(()) } #[test] - fn token_display_str() { + fn token_display_str() -> Result<()> { + assert_eq!( + Val::Str { + text: "Hello You".to_string() + } + .to_string(), + "'Hello You'" + ); + + Ok(()) + } + + #[test] + fn token_display_complex_str() -> Result<()> { assert_eq!( Val::Str { text: "Hello 'You'".to_string() } .to_string(), - "'Hello \'You\''" + "b64'SGVsbG8gJ1lvdSc'" ); + + Ok(()) } #[test] - fn token_null_fn_arg() { + fn token_null_fn_arg() -> Result<()> { assert_eq!( Val::Fn { name: "fn".to_string(), @@ -775,10 +870,12 @@ mod tests { .to_string(), r#"fn(a='aaa')"# ); + + Ok(()) } #[test] - fn token_display_fn() { + fn token_display_fn() -> Result<()> { assert_eq!( Token::Tag { val: Val::Fn { @@ -787,7 +884,7 @@ mod tests { FnArg { name: "arg".to_string(), value: Val::Str { - text: "v".to_string() + text: "v 'x'".to_string() } }, FnArg { @@ -800,12 +897,14 @@ mod tests { } } .to_string(), - r#"${[ foo(arg='v', arg2=my_var) ]}"# + r#"${[ foo(arg=b64'diAneCc', arg2=my_var) ]}"# ); + + Ok(()) } #[test] - fn tokens_display() { + fn tokens_display() -> Result<()> { assert_eq!( Tokens { tokens: vec![ @@ -827,5 +926,7 @@ mod tests { .to_string(), r#"${[ my_var ]} Some cool text ${[ 'Hello World' ]}"# ); + + Ok(()) } } diff --git a/src-tauri/yaak-templates/src/renderer.rs b/src-tauri/yaak-templates/src/renderer.rs index a9e378a37..989c61a60 100644 --- a/src-tauri/yaak-templates/src/renderer.rs +++ b/src-tauri/yaak-templates/src/renderer.rs @@ -1,6 +1,6 @@ use crate::error::Error::{RenderStackExceededError, VariableNotFound}; use crate::error::Result; -use crate::{FnArg, Parser, Token, Tokens, Val}; +use crate::{Parser, Token, Tokens, Val}; use log::warn; use serde_json::json; use std::collections::HashMap; @@ -44,14 +44,14 @@ pub async fn render_json_value_raw( Ok(v) } -async fn parse_and_render_with_depth( +async fn parse_and_render_at_depth( template: &str, vars: &HashMap, cb: &T, depth: usize, ) -> Result { let mut p = Parser::new(template); - let tokens = p.parse(); + let tokens = p.parse()?; render(tokens, vars, cb, depth + 1).await } @@ -60,7 +60,7 @@ pub async fn parse_and_render( vars: &HashMap, cb: &T, ) -> Result { - parse_and_render_with_depth(template, vars, cb, 1).await + parse_and_render_at_depth(template, vars, cb, 1).await } pub async fn render( @@ -79,7 +79,7 @@ pub async fn render( for t in tokens.tokens { match t { Token::Raw { text } => doc_str.push(text), - Token::Tag { val } => doc_str.push(render_tag(val, &vars, cb, depth).await?), + Token::Tag { val } => doc_str.push(render_value(val, &vars, cb, depth).await?), Token::Eof => {} } } @@ -87,44 +87,31 @@ pub async fn render( Ok(doc_str.join("")) } -async fn render_tag( +async fn render_value( val: Val, vars: &HashMap, cb: &T, depth: usize, ) -> Result { let v = match val { - Val::Str { text } => text.into(), + Val::Str { text } => { + let r = Box::pin(parse_and_render_at_depth(&text, vars, cb, depth)).await?; + r.to_string() + } Val::Var { name } => match vars.get(name.as_str()) { Some(v) => { - let r = Box::pin(parse_and_render_with_depth(v, vars, cb, depth)).await?; + let r = Box::pin(parse_and_render_at_depth(v, vars, cb, depth)).await?; r.to_string() } None => return Err(VariableNotFound(name)), }, Val::Bool { value } => value.to_string(), Val::Fn { name, args } => { - let empty = "".to_string(); + // let empty = "".to_string(); let mut resolved_args: HashMap = HashMap::new(); for a in args { - let (k, v) = match a { - FnArg { - name, - value: Val::Str { text }, - } => (name.to_string(), text.to_string()), - FnArg { - name, - value: Val::Var { name: var_name }, - } => ( - name.to_string(), - vars.get(var_name.as_str()).unwrap_or(&empty).to_string(), - ), - FnArg { name, value: val } => { - let r = Box::pin(render_tag(val.clone(), vars, cb, depth)).await?; - (name.to_string(), r) - } - }; - resolved_args.insert(k, v); + let v = Box::pin(render_value(a.value, vars, cb, depth)).await?; + resolved_args.insert(a.name, v); } match cb.run(name.as_str(), resolved_args.clone()).await { Ok(s) => s, @@ -253,6 +240,67 @@ mod parse_and_render_tests { Ok(()) } + #[tokio::test] + async fn render_fn_arg() -> Result<()> { + let vars = HashMap::new(); + let template = r#"${[ upper(foo='bar') ]}"#; + let result = r#"BAR"#; + struct CB {} + impl TemplateCallback for CB { + async fn run(&self, fn_name: &str, args: HashMap) -> Result { + Ok(match fn_name { + "secret" => "abc".to_string(), + "upper" => args["foo"].to_string().to_uppercase(), + _ => "".to_string(), + }) + } + } + + assert_eq!(parse_and_render(template, &vars, &CB {}).await?, result.to_string()); + Ok(()) + } + + #[tokio::test] + async fn render_fn_b64_arg_template() -> Result<()> { + let mut vars = HashMap::new(); + vars.insert("foo".to_string(), "bar".to_string()); + let template = r#"${[ upper(foo=b64'Zm9vICdiYXInIGJheg') ]}"#; + let result = r#"FOO 'BAR' BAZ"#; + struct CB {} + impl TemplateCallback for CB { + async fn run(&self, fn_name: &str, args: HashMap) -> Result { + Ok(match fn_name { + "upper" => args["foo"].to_string().to_uppercase(), + _ => "".to_string(), + }) + } + } + + assert_eq!(parse_and_render(template, &vars, &CB {}).await?, result.to_string()); + Ok(()) + } + + #[tokio::test] + async fn render_fn_arg_template() -> Result<()> { + let mut vars = HashMap::new(); + vars.insert("foo".to_string(), "bar".to_string()); + let template = r#"${[ upper(foo='${[ foo ]}') ]}"#; + let result = r#"BAR"#; + struct CB {} + impl TemplateCallback for CB { + async fn run(&self, fn_name: &str, args: HashMap) -> Result { + Ok(match fn_name { + "secret" => "abc".to_string(), + "upper" => args["foo"].to_string().to_uppercase(), + _ => "".to_string(), + }) + } + } + + assert_eq!(parse_and_render(template, &vars, &CB {}).await?, result.to_string()); + Ok(()) + } + #[tokio::test] async fn render_nested_fn() -> Result<()> { let vars = HashMap::new(); @@ -277,7 +325,6 @@ mod parse_and_render_tests { async fn render_fn_err() -> Result<()> { let vars = HashMap::new(); let template = r#"${[ error() ]}"#; - let result = r#""#; struct CB {} impl TemplateCallback for CB { @@ -286,7 +333,10 @@ mod parse_and_render_tests { } } - assert_eq!(parse_and_render(template, &vars, &CB {}).await?, result.to_string()); + assert_eq!( + parse_and_render(template, &vars, &CB {}).await, + Err(RenderError("Failed to do it!".to_string())) + ); Ok(()) } } diff --git a/src-web/components/TemplateFunctionDialog.tsx b/src-web/components/TemplateFunctionDialog.tsx index 86e77433d..443456de8 100644 --- a/src-web/components/TemplateFunctionDialog.tsx +++ b/src-web/components/TemplateFunctionDialog.tsx @@ -5,10 +5,13 @@ import { useMemo, useState } from 'react'; import { useDebouncedValue } from '../hooks/useDebouncedValue'; import { useRenderTemplate } from '../hooks/useRenderTemplate'; import { useTemplateTokensToString } from '../hooks/useTemplateTokensToString'; +import { useToggle } from '../hooks/useToggle'; import { Button } from './core/Button'; import { InlineCode } from './core/InlineCode'; -import { VStack } from './core/Stacks'; +import { HStack, VStack } from './core/Stacks'; import { DYNAMIC_FORM_NULL_ARG, DynamicForm } from './DynamicForm'; +import { IconButton } from './core/IconButton'; +import { Banner } from './core/Banner'; interface Props { templateFunction: TemplateFunction; @@ -18,6 +21,7 @@ interface Props { } export function TemplateFunctionDialog({ templateFunction, hide, initialTokens, onChange }: Props) { + const [showSecretsInPreview, toggleShowSecretsInPreview] = useToggle(false); const [argValues, setArgValues] = useState>(() => { const initial: Record = {}; const initialArgs = @@ -77,27 +81,65 @@ export function TemplateFunctionDialog({ templateFunction, hide, initialTokens, const debouncedTagText = useDebouncedValue(tagText.data ?? '', 200); const rendered = useRenderTemplate(debouncedTagText); - const tooLarge = (rendered.data ?? '').length > 10000; + const tooLarge = rendered.data ? rendered.data.length > 10000 : false; + const dataContainsSecrets = useMemo(() => { + for (const [name, value] of Object.entries(argValues)) { + const isPassword = templateFunction.args.some( + (a) => a.type === 'text' && a.password && a.name === name, + ); + if (isPassword && typeof value === 'string' && value && rendered.data?.includes(value)) { + return true; + } + } + return false; + // Only update this on rendered data change to keep secrets hidden on input change + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [rendered.data]); return (

{templateFunction.name}(…)

- -
Preview
- - {tooLarge ? 'too large to preview' : rendered.data || <> } - + + +
Rendered Preview
+ +
+ {rendered.error || tagText.error ? ( + {`${rendered.error || tagText.error}`} + ) : ( + + {dataContainsSecrets && !showSecretsInPreview ? ( + ------ sensitive values hidden ------ + ) : tooLarge ? ( + 'too large to preview' + ) : ( + rendered.data || <>  + )} + + )}
- ) : ( + ) : !value.filePath ? ( - Sync workspace data to folder as plain text files, ideal for backup and Git - collaboration. Environments are excluded in order to keep your secrets private. + Sync data to a folder for backup and Git integration. - )} + ) : null} Date: Thu, 20 Mar 2025 06:05:17 -0700 Subject: [PATCH 112/996] Some cleanup around window creation --- src-tauri/src/lib.rs | 154 +--------------- src-tauri/src/tauri_plugin_mac_window.rs | 2 +- src-tauri/src/window.rs | 103 ++++++++++- .../components/Settings/SettingsDesign.tsx | 167 ------------------ .../components/Settings/SettingsGeneral.tsx | 8 - src-web/lib/tauri.ts | 3 +- 6 files changed, 109 insertions(+), 328 deletions(-) delete mode 100644 src-web/components/Settings/SettingsDesign.tsx diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index bd051ff05..220034200 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -12,7 +12,6 @@ use crate::uri_scheme::handle_uri_scheme; use error::Result as YaakResult; use eventsource_client::{EventParser, SSE}; use log::{debug, error, warn}; -use rand::random; use regex::Regex; use std::collections::{BTreeMap, HashMap}; use std::fs::{create_dir_all, File}; @@ -20,7 +19,7 @@ use std::path::PathBuf; use std::str::FromStr; use std::time::Duration; use std::{fs, panic}; -use tauri::{AppHandle, Emitter, RunEvent, State, WebviewWindow}; +use tauri::{is_dev, AppHandle, Emitter, RunEvent, State, WebviewWindow}; use tauri::{Listener, Runtime}; use tauri::{Manager, WindowEvent}; use tauri_plugin_log::fern::colors::ColoredLevelConfig; @@ -68,6 +67,7 @@ use yaak_sse::sse::ServerSentEvent; use yaak_templates::format::format_json; use yaak_templates::{Parser, Tokens}; +mod commands; mod encoding; mod error; mod grpc; @@ -83,15 +83,6 @@ mod uri_scheme; mod window; mod window_menu; -const DEFAULT_WINDOW_WIDTH: f64 = 1100.0; -const DEFAULT_WINDOW_HEIGHT: f64 = 600.0; - -const MIN_WINDOW_WIDTH: f64 = 300.0; -const MIN_WINDOW_HEIGHT: f64 = 300.0; - -const MAIN_WINDOW_PREFIX: &str = "main_"; -const OTHER_WINDOW_PREFIX: &str = "other_"; - #[derive(serde::Serialize)] #[serde(default, rename_all = "camelCase")] struct AppMetaData { @@ -1368,15 +1359,6 @@ async fn cmd_update_folder(folder: Folder, w: WebviewWindow) -> Result Result<(), String> { - if !is_dev() { - panic!("Cannot write arbitrary files when not in dev mode"); - } - - fs::write(pathname, contents).map_err(|e| e.to_string()) -} - #[tauri::command] async fn cmd_delete_folder(w: WebviewWindow, folder_id: &str) -> Result { delete_folder(&w, folder_id, &UpdateSource::Window).await.map_err(|e| e.to_string()) @@ -1632,72 +1614,13 @@ async fn cmd_new_child_window( title: &str, inner_size: (f64, f64), ) -> Result<(), String> { - let app_handle = parent_window.app_handle(); - let label = format!("{OTHER_WINDOW_PREFIX}_{label}"); - let scale_factor = parent_window.scale_factor().unwrap(); - - let current_pos = parent_window.inner_position().unwrap().to_logical::(scale_factor); - let current_size = parent_window.inner_size().unwrap().to_logical::(scale_factor); - - // Position the new window in the middle of the parent - let position = ( - current_pos.x + current_size.width / 2.0 - inner_size.0 / 2.0, - current_pos.y + current_size.height / 2.0 - inner_size.1 / 2.0, - ); - - let config = window::CreateWindowConfig { - label: label.as_str(), - title, - url, - inner_size: Some(inner_size), - position: Some(position), - hide_titlebar: true, - ..Default::default() - }; - - let child_window = window::create_window(&app_handle, config); - - // NOTE: These listeners will remain active even when the windows close. Unfortunately, - // there's no way to unlisten to events for now, so we just have to be defensive. - - { - let parent_window = parent_window.clone(); - let child_window = child_window.clone(); - child_window.clone().on_window_event(move |e| match e { - // When the new window is destroyed, bring the other up behind it - WindowEvent::Destroyed => { - if let Some(w) = parent_window.get_webview_window(child_window.label()) { - w.set_focus().unwrap(); - } - } - _ => {} - }); - } - - { - let parent_window = parent_window.clone(); - let child_window = child_window.clone(); - parent_window.clone().on_window_event(move |e| match e { - // When the parent window is closed, close the child - WindowEvent::CloseRequested { .. } => child_window.destroy().unwrap(), - // When the parent window is focused, bring the child above - WindowEvent::Focused(focus) => { - if *focus { - if let Some(w) = parent_window.get_webview_window(child_window.label()) { - w.set_focus().unwrap(); - }; - } - } - _ => {} - }); - } - + window::create_child_window(&parent_window, url, label, title, inner_size); Ok(()) } #[tauri::command] async fn cmd_new_main_window(app_handle: AppHandle, url: &str) -> Result<(), String> { - create_main_window(&app_handle, url); + window::create_main_window(&app_handle, url); Ok(()) } @@ -1724,33 +1647,6 @@ async fn cmd_check_for_updates( pub fn run() { #[allow(unused_mut)] let mut builder = tauri::Builder::default() - .plugin( - Builder::default() - .targets([ - Target::new(TargetKind::Stdout), - Target::new(TargetKind::LogDir { file_name: None }), - Target::new(TargetKind::Webview), - ]) - .level_for("plugin_runtime", log::LevelFilter::Info) - .level_for("cookie_store", log::LevelFilter::Info) - .level_for("eventsource_client::event_parser", log::LevelFilter::Info) - .level_for("h2", log::LevelFilter::Info) - .level_for("hyper", log::LevelFilter::Info) - .level_for("hyper_util", log::LevelFilter::Info) - .level_for("hyper_rustls", log::LevelFilter::Info) - .level_for("reqwest", log::LevelFilter::Info) - .level_for("sqlx", log::LevelFilter::Warn) - .level_for("tao", log::LevelFilter::Info) - .level_for("tokio_util", log::LevelFilter::Info) - .level_for("tonic", log::LevelFilter::Info) - .level_for("tower", log::LevelFilter::Info) - .level_for("tracing", log::LevelFilter::Warn) - .level_for("swc_ecma_codegen", log::LevelFilter::Off) - .level_for("swc_ecma_transforms_base", log::LevelFilter::Off) - .with_colors(ColoredLevelConfig::default()) - .level(if is_dev() { log::LevelFilter::Debug } else { log::LevelFilter::Info }) - .build(), - ) .plugin( Builder::default() .targets([ @@ -1905,7 +1801,6 @@ pub fn run() { cmd_update_settings, cmd_update_workspace, cmd_update_workspace_meta, - cmd_write_file_dev, ]) .register_uri_scheme_protocol("yaak", handle_uri_scheme) .build(tauri::generate_context!()) @@ -1913,7 +1808,7 @@ pub fn run() { .run(|app_handle, event| { match event { RunEvent::Ready => { - let w = create_main_window(app_handle, "/"); + let w = window::create_main_window(app_handle, "/"); tauri::async_runtime::spawn(async move { let info = history::store_launch_history(&w).await; debug!("Launched Yaak {:?}", info); @@ -1973,45 +1868,6 @@ pub fn run() { }); } -fn is_dev() -> bool { - #[cfg(dev)] - { - return true; - } - #[cfg(not(dev))] - { - return false; - } -} - -fn create_main_window(handle: &AppHandle, url: &str) -> WebviewWindow { - let mut counter = 0; - let label = loop { - let label = format!("{MAIN_WINDOW_PREFIX}{counter}"); - match handle.webview_windows().get(label.as_str()) { - None => break Some(label), - Some(_) => counter += 1, - } - } - .expect("Failed to generate label for new window"); - - let config = window::CreateWindowConfig { - url, - label: label.as_str(), - title: "Yaak", - inner_size: Some((DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT)), - position: Some(( - // Offset by random amount so it's easier to differentiate - 100.0 + random::() * 20.0, - 100.0 + random::() * 20.0, - )), - hide_titlebar: true, - ..Default::default() - }; - - window::create_window(handle, config) -} - async fn get_update_mode(h: &AppHandle) -> UpdateMode { let settings = get_or_create_settings(h).await; UpdateMode::new(settings.update_channel.as_str()) diff --git a/src-tauri/src/tauri_plugin_mac_window.rs b/src-tauri/src/tauri_plugin_mac_window.rs index dd70a2b79..0b09654dd 100644 --- a/src-tauri/src/tauri_plugin_mac_window.rs +++ b/src-tauri/src/tauri_plugin_mac_window.rs @@ -1,4 +1,4 @@ -use crate::MAIN_WINDOW_PREFIX; +use crate::window::MAIN_WINDOW_PREFIX; use hex_color::HexColor; use log::warn; use objc::{msg_send, sel, sel_impl}; diff --git a/src-tauri/src/window.rs b/src-tauri/src/window.rs index ae73aff81..c7d31b60f 100644 --- a/src-tauri/src/window.rs +++ b/src-tauri/src/window.rs @@ -1,6 +1,6 @@ use crate::window_menu::app_menu; -use crate::{DEFAULT_WINDOW_HEIGHT, DEFAULT_WINDOW_WIDTH, MIN_WINDOW_HEIGHT, MIN_WINDOW_WIDTH}; use log::{info, warn}; +use rand::random; use std::process::exit; use tauri::{ AppHandle, Emitter, LogicalSize, Manager, Runtime, WebviewUrl, WebviewWindow, WindowEvent, @@ -8,6 +8,15 @@ use tauri::{ use tauri_plugin_opener::OpenerExt; use tokio::sync::mpsc; +const DEFAULT_WINDOW_WIDTH: f64 = 1100.0; +const DEFAULT_WINDOW_HEIGHT: f64 = 600.0; + +const MIN_WINDOW_WIDTH: f64 = 300.0; +const MIN_WINDOW_HEIGHT: f64 = 300.0; + +pub(crate) const MAIN_WINDOW_PREFIX: &str = "main_"; +const OTHER_WINDOW_PREFIX: &str = "other_"; + #[derive(Default, Debug)] pub(crate) struct CreateWindowConfig<'s> { pub url: &'s str, @@ -161,3 +170,95 @@ pub(crate) fn create_window( win } + +pub(crate) fn create_main_window(handle: &AppHandle, url: &str) -> WebviewWindow { + let mut counter = 0; + let label = loop { + let label = format!("{MAIN_WINDOW_PREFIX}{counter}"); + match handle.webview_windows().get(label.as_str()) { + None => break Some(label), + Some(_) => counter += 1, + } + } + .expect("Failed to generate label for new window"); + + let config = CreateWindowConfig { + url, + label: label.as_str(), + title: "Yaak", + inner_size: Some((DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT)), + position: Some(( + // Offset by random amount so it's easier to differentiate + 100.0 + random::() * 20.0, + 100.0 + random::() * 20.0, + )), + hide_titlebar: true, + ..Default::default() + }; + + create_window(handle, config) +} + +pub(crate) fn create_child_window(parent_window: &WebviewWindow, url: &str, label: &str, title: &str, inner_size: (f64, f64)) -> WebviewWindow { + let app_handle = parent_window.app_handle(); + let label = format!("{OTHER_WINDOW_PREFIX}_{label}"); + let scale_factor = parent_window.scale_factor().unwrap(); + + let current_pos = parent_window.inner_position().unwrap().to_logical::(scale_factor); + let current_size = parent_window.inner_size().unwrap().to_logical::(scale_factor); + + // Position the new window in the middle of the parent + let position = ( + current_pos.x + current_size.width / 2.0 - inner_size.0 / 2.0, + current_pos.y + current_size.height / 2.0 - inner_size.1 / 2.0, + ); + + let config = CreateWindowConfig { + label: label.as_str(), + title, + url, + inner_size: Some(inner_size), + position: Some(position), + hide_titlebar: true, + ..Default::default() + }; + + let child_window = create_window(&app_handle, config); + + // NOTE: These listeners will remain active even when the windows close. Unfortunately, + // there's no way to unlisten to events for now, so we just have to be defensive. + + { + let parent_window = parent_window.clone(); + let child_window = child_window.clone(); + child_window.clone().on_window_event(move |e| match e { + // When the new window is destroyed, bring the other up behind it + WindowEvent::Destroyed => { + if let Some(w) = parent_window.get_webview_window(child_window.label()) { + w.set_focus().unwrap(); + } + } + _ => {} + }); + } + + { + let parent_window = parent_window.clone(); + let child_window = child_window.clone(); + parent_window.clone().on_window_event(move |e| match e { + // When the parent window is closed, close the child + WindowEvent::CloseRequested { .. } => child_window.destroy().unwrap(), + // When the parent window is focused, bring the child above + WindowEvent::Focused(focus) => { + if *focus { + if let Some(w) = parent_window.get_webview_window(child_window.label()) { + w.set_focus().unwrap(); + }; + } + } + _ => {} + }); + } + + child_window +} diff --git a/src-web/components/Settings/SettingsDesign.tsx b/src-web/components/Settings/SettingsDesign.tsx deleted file mode 100644 index b7f637060..000000000 --- a/src-web/components/Settings/SettingsDesign.tsx +++ /dev/null @@ -1,167 +0,0 @@ -import { open } from '@tauri-apps/plugin-dialog'; -import React, { useState } from 'react'; -import { useLocalStorage } from 'react-use'; -import { capitalize } from '../../lib/capitalize'; -import { invokeCmd } from '../../lib/tauri'; -import { getThemes } from '../../lib/theme/themes'; -import { yaakDark } from '../../lib/theme/themes/yaak'; -import { getThemeCSS } from '../../lib/theme/window'; -import { Banner } from '../core/Banner'; -import { Button } from '../core/Button'; -import {Editor} from "../core/Editor/Editor"; -import type { IconProps } from '../core/Icon'; -import { Icon } from '../core/Icon'; -import { IconButton } from '../core/IconButton'; -import { InlineCode } from '../core/InlineCode'; -import { Input } from '../core/Input'; -import { Separator } from '../core/Separator'; -import { HStack, VStack } from '../core/Stacks'; - -const buttonColors = [ - 'primary', - 'secondary', - 'info', - 'success', - 'warning', - 'danger', - 'default', -] as const; - -const icons: IconProps['icon'][] = [ - 'info', - 'box', - 'update', - 'alert_triangle', - 'arrow_big_right_dash', - 'download', - 'copy', - 'magic_wand', - 'settings', - 'trash', - 'sparkles', - 'pencil', - 'paste', - 'search', - 'send_horizontal', -]; - -const themes = getThemes(); - -export function SettingsDesign() { - const [exportDir, setExportDir] = useLocalStorage('theme_export_dir', null); - const [loadingExport, setLoadingExport] = useState(false); - - const saveThemes = () => { - setLoadingExport(true); - setTimeout(async () => { - const allThemesCSS = themes.themes.map(getThemeCSS).join('\n\n'); - const coreThemeCSS = [yaakDark].map(getThemeCSS).join('\n\n'); - - try { - await invokeCmd('cmd_write_file_dev', { - pathname: exportDir + '/themes-all.css', - contents: allThemesCSS, - }); - await invokeCmd('cmd_write_file_dev', { - pathname: exportDir + '/themes-slim.css', - contents: coreThemeCSS, - }); - } catch (err) { - console.log('FAILED', err); - } - setLoadingExport(false); - }, 500); - }; - - return ( -
- - {exportDir} - - - - - - - } - stateKey={null} - /> - -
-
- {buttonColors.map((c, i) => ( - - ))} -
-
- {buttonColors.map((c, i) => ( - - ))} -
-
- {icons.map((v, i) => ( - - ))} -
-
-
- Primary banner - Secondary banner - Danger banner - Warning banner - Success banner -
-
- ); -} diff --git a/src-web/components/Settings/SettingsGeneral.tsx b/src-web/components/Settings/SettingsGeneral.tsx index 811ed4037..159b94239 100644 --- a/src-web/components/Settings/SettingsGeneral.tsx +++ b/src-web/components/Settings/SettingsGeneral.tsx @@ -77,14 +77,6 @@ export function SettingsGeneral() { ]} /> - {}} - /> - diff --git a/src-web/lib/tauri.ts b/src-web/lib/tauri.ts index bedd1f1b4..a354fb7ea 100644 --- a/src-web/lib/tauri.ts +++ b/src-web/lib/tauri.ts @@ -78,8 +78,7 @@ type TauriCmd = | 'cmd_update_http_request' | 'cmd_update_settings' | 'cmd_update_workspace' - | 'cmd_update_workspace_meta' - | 'cmd_write_file_dev'; + | 'cmd_update_workspace_meta'; export async function invokeCmd(cmd: TauriCmd, args?: InvokeArgs): Promise { // console.log('RUN COMMAND', cmd, args); From aa75636026dd9a1b3ddb5bc2db989c073ebeeed8 Mon Sep 17 00:00:00 2001 From: Andy Bao Date: Thu, 20 Mar 2025 09:07:31 -0400 Subject: [PATCH 113/996] Fix labels in GRPC service/method selector dropdown (#188) --- src-web/components/GrpcConnectionSetupPane.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-web/components/GrpcConnectionSetupPane.tsx b/src-web/components/GrpcConnectionSetupPane.tsx index beab1715f..c5436e25a 100644 --- a/src-web/components/GrpcConnectionSetupPane.tsx +++ b/src-web/components/GrpcConnectionSetupPane.tsx @@ -92,7 +92,7 @@ export function GrpcConnectionSetupPane({ const options = services?.flatMap((s) => s.methods.map((m) => ({ - label: `${s.name.split('.', 2).pop() ?? s.name}/${m.name}`, + label: `${s.name.split('.').pop() ?? s.name}/${m.name}`, value: `${s.name}/${m.name}`, })), ) ?? []; From cf8f8743bbf74b4f748c5bed6038ad914c622a3a Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 20 Mar 2025 06:23:36 -0700 Subject: [PATCH 114/996] Remove non-existing import --- src-tauri/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 220034200..a2e17af20 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -67,7 +67,6 @@ use yaak_sse::sse::ServerSentEvent; use yaak_templates::format::format_json; use yaak_templates::{Parser, Tokens}; -mod commands; mod encoding; mod error; mod grpc; From 4c4eaba7d220657855177853b95e1e984fb97f76 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 20 Mar 2025 09:43:14 -0700 Subject: [PATCH 115/996] Queries now use AppHandle instead of Window (#189) --- src-tauri/src/history.rs | 32 +- src-tauri/src/http_request.rs | 110 +++- src-tauri/src/lib.rs | 605 +++++++++++------- src-tauri/src/notifications.rs | 22 +- src-tauri/src/plugin_events.rs | 12 +- src-tauri/yaak-license/src/license.rs | 22 +- src-tauri/yaak-models/bindings/gen_models.ts | 4 +- src-tauri/yaak-models/src/error.rs | 6 + src-tauri/yaak-models/src/lib.rs | 1 + src-tauri/yaak-models/src/manager.rs | 40 ++ src-tauri/yaak-models/src/queries.rs | 591 ++++++++--------- src-tauri/yaak-sync/src/commands.rs | 22 +- src-tauri/yaak-sync/src/sync.rs | 57 +- src-tauri/yaak-templates/src/renderer.rs | 11 +- src-tauri/yaak-ws/src/commands.rs | 99 +-- .../components/GrpcConnectionSetupPane.tsx | 15 +- src-web/components/HttpRequestPane.tsx | 23 +- src-web/components/WebsocketRequestPane.tsx | 20 +- src-web/hooks/useSyncModelStores.ts | 31 +- 19 files changed, 1023 insertions(+), 700 deletions(-) create mode 100644 src-tauri/yaak-models/src/manager.rs diff --git a/src-tauri/src/history.rs b/src-tauri/src/history.rs index 0e430bfaf..7bc5ff35d 100644 --- a/src-tauri/src/history.rs +++ b/src-tauri/src/history.rs @@ -1,8 +1,7 @@ -use tauri::{Manager, Runtime, WebviewWindow}; +use tauri::{AppHandle, Runtime}; use yaak_models::queries::{ - get_key_value_int, get_key_value_string, - set_key_value_int, set_key_value_string, UpdateSource, + get_key_value_int, get_key_value_string, set_key_value_int, set_key_value_string, UpdateSource, }; const NAMESPACE: &str = "analytics"; @@ -16,14 +15,15 @@ pub struct LaunchEventInfo { pub num_launches: i32, } -pub async fn store_launch_history(w: &WebviewWindow) -> LaunchEventInfo { +pub async fn store_launch_history(app_handle: &AppHandle) -> LaunchEventInfo { let last_tracked_version_key = "last_tracked_version"; let mut info = LaunchEventInfo::default(); - info.num_launches = get_num_launches(w).await + 1; - info.previous_version = get_key_value_string(w, NAMESPACE, last_tracked_version_key, "").await; - info.current_version = w.package_info().version.to_string(); + info.num_launches = get_num_launches(app_handle).await + 1; + info.previous_version = + get_key_value_string(app_handle, NAMESPACE, last_tracked_version_key, "").await; + info.current_version = app_handle.package_info().version.to_string(); if info.previous_version.is_empty() { } else { @@ -33,16 +33,22 @@ pub async fn store_launch_history(w: &WebviewWindow) -> LaunchEve // Update key values set_key_value_string( - w, + app_handle, NAMESPACE, last_tracked_version_key, info.current_version.as_str(), &UpdateSource::Background, ) .await; - - set_key_value_int(w, NAMESPACE, NUM_LAUNCHES_KEY, info.num_launches, &UpdateSource::Background) - .await; + + set_key_value_int( + app_handle, + NAMESPACE, + NUM_LAUNCHES_KEY, + info.num_launches, + &UpdateSource::Background, + ) + .await; info } @@ -59,6 +65,6 @@ pub fn get_os() -> &'static str { } } -pub async fn get_num_launches(w: &WebviewWindow) -> i32 { - get_key_value_int(w, NAMESPACE, NUM_LAUNCHES_KEY, 0).await +pub async fn get_num_launches(app_handle: &AppHandle) -> i32 { + get_key_value_int(app_handle, NAMESPACE, NUM_LAUNCHES_KEY, 0).await } diff --git a/src-tauri/src/http_request.rs b/src-tauri/src/http_request.rs index d19c9a296..ec2f0902b 100644 --- a/src-tauri/src/http_request.rs +++ b/src-tauri/src/http_request.rs @@ -46,18 +46,22 @@ pub async fn send_http_request( cookie_jar: Option, cancelled_rx: &mut Receiver, ) -> Result { - let plugin_manager = window.state::(); - let workspace = get_workspace(window, &unrendered_request.workspace_id).await?; - let base_environment = get_base_environment(window, &unrendered_request.workspace_id).await?; - let settings = get_or_create_settings(window).await; + let app_handle = window.app_handle().clone(); + let plugin_manager = app_handle.state::(); + let workspace = get_workspace(&app_handle, &unrendered_request.workspace_id).await?; + let base_environment = + get_base_environment(&app_handle, &unrendered_request.workspace_id).await?; + let settings = get_or_create_settings(&app_handle).await; + + let response_id = og_response.id.clone(); + let response = Arc::new(Mutex::new(og_response.clone())); + let cb = PluginTemplateCallback::new( window.app_handle(), &WindowContext::from_window(window), RenderPurpose::Send, ); - - let response_id = og_response.id.clone(); - let response = Arc::new(Mutex::new(og_response.clone())); + let update_source = UpdateSource::from_window(window); let request = match render_http_request( &unrendered_request, @@ -68,7 +72,15 @@ pub async fn send_http_request( .await { Ok(r) => r, - Err(e) => return Ok(response_err(&*response.lock().await, e.to_string(), window).await), + Err(e) => { + return Ok(response_err( + &app_handle, + &*response.lock().await, + e.to_string(), + &update_source, + ) + .await) + } }; let mut url_string = request.url; @@ -178,9 +190,10 @@ pub async fn send_http_request( Ok(u) => u, Err(e) => { return Ok(response_err( + &app_handle, &*response.lock().await, format!("Failed to parse URL \"{}\": {}", url_string, e.to_string()), - window, + &update_source, ) .await); } @@ -190,9 +203,10 @@ pub async fn send_http_request( Ok(u) => u, Err(e) => { return Ok(response_err( + &app_handle, &*response.lock().await, format!("Failed to parse URL \"{}\": {}", url_string, e.to_string()), - window, + &update_source, ) .await); } @@ -296,7 +310,13 @@ pub async fn send_http_request( request_builder = request_builder.body(f); } Err(e) => { - return Ok(response_err(&*response.lock().await, e, window).await); + return Ok(response_err( + &app_handle, + &*response.lock().await, + e, + &update_source, + ) + .await); } } } else if body_type == "multipart/form-data" && request_body.contains_key("form") { @@ -323,9 +343,10 @@ pub async fn send_http_request( Ok(f) => multipart::Part::bytes(f), Err(e) => { return Ok(response_err( + &app_handle, &*response.lock().await, e.to_string(), - window, + &update_source, ) .await); } @@ -340,9 +361,10 @@ pub async fn send_http_request( Ok(p) => p, Err(e) => { return Ok(response_err( + &app_handle, &*response.lock().await, format!("Invalid mime for multi-part entry {e:?}"), - window, + &update_source, ) .await); } @@ -356,9 +378,10 @@ pub async fn send_http_request( Ok(p) => p, Err(e) => { return Ok(response_err( + &app_handle, &*response.lock().await, format!("Invalid mime for multi-part entry {e:?}"), - window, + &update_source, ) .await); } @@ -397,7 +420,13 @@ pub async fn send_http_request( Ok(r) => r, Err(e) => { warn!("Failed to build request builder {e:?}"); - return Ok(response_err(&*response.lock().await, e.to_string(), window).await); + return Ok(response_err( + &app_handle, + &*response.lock().await, + e.to_string(), + &update_source, + ) + .await); } }; @@ -423,7 +452,13 @@ pub async fn send_http_request( let plugin_result = match auth_result { Ok(r) => r, Err(e) => { - return Ok(response_err(&*response.lock().await, e.to_string(), window).await); + return Ok(response_err( + &app_handle, + &*response.lock().await, + e.to_string(), + &update_source, + ) + .await); } }; @@ -449,21 +484,23 @@ pub async fn send_http_request( Ok(r) = resp_rx => r, _ = cancelled_rx.changed() => { debug!("Request cancelled"); - return Ok(response_err(&*response.lock().await, "Request was cancelled".to_string(), window).await); + return Ok(response_err(&app_handle, &*response.lock().await, "Request was cancelled".to_string(), &update_source).await); } }; { + let app_handle = app_handle.clone(); let window = window.clone(); let cancelled_rx = cancelled_rx.clone(); let response_id = response_id.clone(); let response = response.clone(); + let update_source = update_source.clone(); tokio::spawn(async move { match raw_response { Ok(mut v) => { let content_length = v.content_length(); let response_headers = v.headers().clone(); - let dir = window.app_handle().path().app_data_dir().unwrap(); + let dir = app_handle.path().app_data_dir().unwrap(); let base_dir = dir.join("responses"); create_dir_all(base_dir.clone()).await.expect("Failed to create responses dir"); let body_path = if response_id.is_empty() { @@ -497,7 +534,7 @@ pub async fn send_http_request( }; r.state = HttpResponseState::Connected; - update_response_if_id(&window, &r, &UpdateSource::Window) + update_response_if_id(&app_handle, &r, &update_source) .await .expect("Failed to update response after connected"); } @@ -526,7 +563,7 @@ pub async fn send_http_request( f.flush().await.expect("Failed to flush file"); written_bytes += bytes.len(); r.content_length = Some(written_bytes as i32); - update_response_if_id(&window, &r, &UpdateSource::Window) + update_response_if_id(&app_handle, &r, &update_source) .await .expect("Failed to update response"); } @@ -534,7 +571,13 @@ pub async fn send_http_request( break; } Err(e) => { - response_err(&*response.lock().await, e.to_string(), &window).await; + response_err( + &app_handle, + &*response.lock().await, + e.to_string(), + &update_source, + ) + .await; break; } } @@ -548,7 +591,7 @@ pub async fn send_http_request( None => Some(written_bytes as i32), }; r.state = HttpResponseState::Closed; - update_response_if_id(&window, &r, &UpdateSource::Window) + update_response_if_id(&app_handle, &r, &UpdateSource::from_window(&window)) .await .expect("Failed to update response"); }; @@ -574,8 +617,12 @@ pub async fn send_http_request( }) .collect::>(); cookie_jar.cookies = json_cookies; - if let Err(e) = - upsert_cookie_jar(&window, &cookie_jar, &UpdateSource::Window).await + if let Err(e) = upsert_cookie_jar( + &app_handle, + &cookie_jar, + &UpdateSource::from_window(&window), + ) + .await { error!("Failed to update cookie jar: {}", e); }; @@ -583,7 +630,13 @@ pub async fn send_http_request( } Err(e) => { warn!("Failed to execute request {e}"); - response_err(&*response.lock().await, format!("{e} → {e:?}"), &window).await; + response_err( + &app_handle, + &*response.lock().await, + format!("{e} → {e:?}"), + &update_source, + ) + .await; } }; @@ -592,16 +645,17 @@ pub async fn send_http_request( }); }; + let app_handle = app_handle.clone(); Ok(tokio::select! { Ok(r) = done_rx => r, _ = cancelled_rx.changed() => { - match get_http_response(window, response_id.as_str()).await { + match get_http_response(&app_handle, response_id.as_str()).await { Ok(mut r) => { r.state = HttpResponseState::Closed; - update_response_if_id(&window, &r, &UpdateSource::Window).await.expect("Failed to update response") + update_response_if_id(&app_handle, &r, &UpdateSource::from_window(window)).await.expect("Failed to update response") }, _ => { - response_err(&*response.lock().await, "Ephemeral request was cancelled".to_string(), &window).await + response_err(&app_handle, &*response.lock().await, "Ephemeral request was cancelled".to_string(), &update_source).await }.clone(), } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index a2e17af20..b275ce1a0 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -124,10 +124,10 @@ async fn cmd_render_template( environment_id: Option<&str>, ) -> YaakResult { let environment = match environment_id { - Some(id) => get_environment(&window, id).await.ok(), + Some(id) => get_environment(&app_handle, id).await.ok(), None => None, }; - let base_environment = get_base_environment(&window, &workspace_id).await?; + let base_environment = get_base_environment(&app_handle, &workspace_id).await?; let result = render_template( template, &base_environment, @@ -155,10 +155,10 @@ async fn cmd_dismiss_notification( async fn cmd_grpc_reflect( request_id: &str, proto_files: Vec, - window: WebviewWindow, + app_handle: AppHandle, grpc_handle: State<'_, Mutex>, ) -> Result, String> { - let req = get_grpc_request(&window, request_id) + let req = get_grpc_request(&app_handle, request_id) .await .map_err(|e| e.to_string())? .ok_or("Failed to find GRPC request")?; @@ -181,24 +181,26 @@ async fn cmd_grpc_go( request_id: &str, environment_id: Option<&str>, proto_files: Vec, + app_handle: AppHandle, window: WebviewWindow, plugin_manager: State<'_, PluginManager>, grpc_handle: State<'_, Mutex>, ) -> YaakResult { let environment = match environment_id { - Some(id) => get_environment(&window, id).await.ok(), + Some(id) => get_environment(&app_handle, id).await.ok(), None => None, }; - let unrendered_request = get_grpc_request(&window, request_id) + let unrendered_request = get_grpc_request(&app_handle, request_id) .await? .ok_or(GenericError("Failed to get GRPC request".to_string()))?; - let base_environment = get_base_environment(&window, &unrendered_request.workspace_id).await?; + let base_environment = + get_base_environment(&app_handle, &unrendered_request.workspace_id).await?; let request = render_grpc_request( &unrendered_request, &base_environment, environment.as_ref(), &PluginTemplateCallback::new( - window.app_handle(), + &app_handle, &WindowContext::from_window(&window), RenderPurpose::Send, ), @@ -242,7 +244,7 @@ async fn cmd_grpc_go( } let conn = upsert_grpc_connection( - &window, + &app_handle, &GrpcConnection { workspace_id: request.workspace_id.clone(), request_id: request.id.clone(), @@ -252,7 +254,7 @@ async fn cmd_grpc_go( url: request.url.clone(), ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await?; @@ -296,14 +298,14 @@ async fn cmd_grpc_go( Ok(c) => c, Err(err) => { upsert_grpc_connection( - &window, + &app_handle, &GrpcConnection { elapsed: start.elapsed().as_millis() as i32, error: Some(err.clone()), state: GrpcConnectionState::Closed, ..conn.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await?; return Ok(conn_id); @@ -322,6 +324,7 @@ async fn cmd_grpc_go( let cb = { let cancelled_rx = cancelled_rx.clone(); + let app_handle = app_handle.clone(); let window = window.clone(); let workspace = base_environment.clone(); let environment = environment.clone(); @@ -346,6 +349,7 @@ async fn cmd_grpc_go( match serde_json::from_str::(ev.payload()) { Ok(IncomingMsg::Message(msg)) => { let window = window.clone(); + let app_handle = app_handle.clone(); let base_msg = base_msg.clone(); let method_desc = method_desc.clone(); let msg = block_in_place(|| { @@ -355,7 +359,7 @@ async fn cmd_grpc_go( &workspace, environment.as_ref(), &PluginTemplateCallback::new( - window.app_handle(), + &app_handle, &WindowContext::from_window(&window), RenderPurpose::Send, ), @@ -370,13 +374,13 @@ async fn cmd_grpc_go( Err(e) => { tauri::async_runtime::spawn(async move { upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { event_type: GrpcEventType::Error, content: e.to_string(), ..base_msg.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -387,13 +391,13 @@ async fn cmd_grpc_go( in_msg_tx.try_send(d_msg).unwrap(); tauri::async_runtime::spawn(async move { upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { content: msg, event_type: GrpcEventType::ClientMessage, ..base_msg.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -411,10 +415,11 @@ async fn cmd_grpc_go( } } }; - let event_handler = window.listen_any(format!("grpc_client_msg_{}", conn.id).as_str(), cb); + let event_handler = app_handle.listen_any(format!("grpc_client_msg_{}", conn.id).as_str(), cb); let grpc_listen = { let window = window.clone(); + let app_handle = app_handle.clone(); let base_event = base_msg.clone(); let req = request.clone(); let msg = if req.message.is_empty() { "{}".to_string() } else { req.message }; @@ -423,7 +428,7 @@ async fn cmd_grpc_go( &base_environment.clone(), environment.as_ref(), &PluginTemplateCallback::new( - window.app_handle(), + &app_handle, &WindowContext::from_window(&window), RenderPurpose::Send, ), @@ -431,14 +436,14 @@ async fn cmd_grpc_go( .await?; upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { content: format!("Connecting to {}", req.url), event_type: GrpcEventType::ConnectionStart, metadata: metadata.clone(), ..base_event.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await?; @@ -470,13 +475,13 @@ async fn cmd_grpc_go( if !method_desc.is_client_streaming() { upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { event_type: GrpcEventType::ClientMessage, content: msg, ..base_event.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -485,7 +490,7 @@ async fn cmd_grpc_go( match maybe_msg { Some(Ok(msg)) => { upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { metadata: metadata_to_map(msg.metadata().clone()), content: if msg.metadata().len() == 0 { @@ -497,37 +502,37 @@ async fn cmd_grpc_go( event_type: GrpcEventType::Info, ..base_event.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { content: serialize_message(&msg.into_inner()).unwrap(), event_type: GrpcEventType::ServerMessage, ..base_event.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { content: "Connection complete".to_string(), event_type: GrpcEventType::ConnectionEnd, status: Some(Code::Ok as i32), ..base_event.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); } Some(Err(e)) => { upsert_grpc_event( - &window, + &app_handle, &(match e.status { Some(s) => GrpcEvent { error: Some(s.message().to_string()), @@ -545,7 +550,7 @@ async fn cmd_grpc_go( ..base_event.clone() }, }), - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -558,7 +563,7 @@ async fn cmd_grpc_go( let mut stream = match maybe_stream { Some(Ok(stream)) => { upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { metadata: metadata_to_map(stream.metadata().clone()), content: if stream.metadata().len() == 0 { @@ -570,7 +575,7 @@ async fn cmd_grpc_go( event_type: GrpcEventType::Info, ..base_event.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -579,7 +584,7 @@ async fn cmd_grpc_go( Some(Err(e)) => { warn!("GRPC stream error {e:?}"); upsert_grpc_event( - &window, + &app_handle, &(match e.status { Some(s) => GrpcEvent { error: Some(s.message().to_string()), @@ -597,7 +602,7 @@ async fn cmd_grpc_go( ..base_event.clone() }, }), - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -611,13 +616,13 @@ async fn cmd_grpc_go( Ok(Some(msg)) => { let message = serialize_message(&msg).unwrap(); upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { content: message, event_type: GrpcEventType::ServerMessage, ..base_event.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -626,7 +631,7 @@ async fn cmd_grpc_go( let trailers = stream.trailers().await.unwrap_or_default().unwrap_or_default(); upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { content: "Connection complete".to_string(), status: Some(Code::Ok as i32), @@ -634,7 +639,7 @@ async fn cmd_grpc_go( event_type: GrpcEventType::ConnectionEnd, ..base_event.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -642,7 +647,7 @@ async fn cmd_grpc_go( } Err(status) => { upsert_grpc_event( - &window, + &app_handle, &GrpcEvent { content: status.to_string(), status: Some(status.code() as i32), @@ -650,7 +655,7 @@ async fn cmd_grpc_go( event_type: GrpcEventType::ConnectionEnd, ..base_event.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -663,7 +668,7 @@ async fn cmd_grpc_go( { let conn_id = conn_id.clone(); tauri::async_runtime::spawn(async move { - let w = window.clone(); + let w = app_handle.clone(); tokio::select! { _ = grpc_listen => { let events = list_grpc_events(&w, &conn_id) @@ -681,7 +686,7 @@ async fn cmd_grpc_go( state: GrpcConnectionState::Closed, ..get_grpc_connection(&w, &conn_id).await.unwrap().clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ).await.unwrap(); }, _ = cancelled_rx.changed() => { @@ -693,7 +698,7 @@ async fn cmd_grpc_go( status: Some(Code::Cancelled as i32), ..base_msg.clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ).await.unwrap(); upsert_grpc_connection( &w, @@ -703,7 +708,7 @@ async fn cmd_grpc_go( state: GrpcConnectionState::Closed, ..get_grpc_connection(&w, &conn_id).await.unwrap().clone() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -717,20 +722,23 @@ async fn cmd_grpc_go( } #[tauri::command] -async fn cmd_send_ephemeral_request( +async fn cmd_send_ephemeral_request( mut request: HttpRequest, environment_id: Option<&str>, cookie_jar_id: Option<&str>, window: WebviewWindow, + app_handle: AppHandle, ) -> YaakResult { let response = HttpResponse::new(); request.id = "".to_string(); let environment = match environment_id { - Some(id) => Some(get_environment(&window, id).await.expect("Failed to get environment")), + Some(id) => { + Some(get_environment(&app_handle, id).await.expect("Failed to get environment")) + } None => None, }; let cookie_jar = match cookie_jar_id { - Some(id) => Some(get_cookie_jar(&window, id).await.expect("Failed to get cookie jar")), + Some(id) => Some(get_cookie_jar(&app_handle, id).await.expect("Failed to get cookie jar")), None => None, }; @@ -752,12 +760,13 @@ async fn cmd_format_json(text: &str) -> Result { #[tauri::command] async fn cmd_filter_response( window: WebviewWindow, + app_handle: AppHandle, response_id: &str, plugin_manager: State<'_, PluginManager>, filter: &str, ) -> Result { let response = - get_http_response(&window, response_id).await.expect("Failed to get http response"); + get_http_response(&app_handle, response_id).await.expect("Failed to get http response"); if let None = response.body_path { return Err("Response body path not set".to_string()); @@ -804,6 +813,7 @@ async fn cmd_get_sse_events(file_path: &str) -> Result, Str #[tauri::command] async fn cmd_import_data( window: WebviewWindow, + app_handle: AppHandle, plugin_manager: State<'_, PluginManager>, file_path: &str, ) -> Result { @@ -915,7 +925,7 @@ async fn cmd_import_data( .collect(); let upserted = batch_upsert( - &window, + &app_handle, workspaces, environments, folders, @@ -1017,15 +1027,16 @@ async fn cmd_curl_to_request( } #[tauri::command] -async fn cmd_export_data( - window: WebviewWindow, +async fn cmd_export_data( + app_handle: AppHandle, export_path: &str, workspace_ids: Vec<&str>, include_environments: bool, ) -> Result<(), String> { - let export_data = get_workspace_export_resources(&window, workspace_ids, include_environments) - .await - .map_err(|e| e.to_string())?; + let export_data = + get_workspace_export_resources(&app_handle, workspace_ids, include_environments) + .await + .map_err(|e| e.to_string())?; let f = File::options() .create(true) .truncate(true) @@ -1043,12 +1054,12 @@ async fn cmd_export_data( } #[tauri::command] -async fn cmd_save_response( - window: WebviewWindow, +async fn cmd_save_response( + app_handle: AppHandle, response_id: &str, filepath: &str, ) -> Result<(), String> { - let response = get_http_response(&window, response_id).await.map_err(|e| e.to_string())?; + let response = get_http_response(&app_handle, response_id).await.map_err(|e| e.to_string())?; let body_path = match response.body_path { None => { @@ -1063,8 +1074,9 @@ async fn cmd_save_response( } #[tauri::command] -async fn cmd_send_http_request( - window: WebviewWindow, +async fn cmd_send_http_request( + app_handle: AppHandle, + window: WebviewWindow, environment_id: Option<&str>, cookie_jar_id: Option<&str>, // NOTE: We receive the entire request because to account for the race @@ -1073,17 +1085,18 @@ async fn cmd_send_http_request( request: HttpRequest, ) -> YaakResult { let response = - create_default_http_response(&window, &request.id, &UpdateSource::Window).await?; + create_default_http_response(&app_handle, &request.id, &UpdateSource::from_window(&window)) + .await?; let (cancel_tx, mut cancel_rx) = tokio::sync::watch::channel(false); - window.listen_any(format!("cancel_http_response_{}", response.id), move |_event| { + app_handle.listen_any(format!("cancel_http_response_{}", response.id), move |_event| { if let Err(e) = cancel_tx.send(true) { warn!("Failed to send cancel event for request {e:?}"); } }); let environment = match environment_id { - Some(id) => match get_environment(&window, id).await { + Some(id) => match get_environment(&app_handle, id).await { Ok(env) => Some(env), Err(e) => { warn!("Failed to find environment by id {id} {}", e); @@ -1094,7 +1107,7 @@ async fn cmd_send_http_request( }; let cookie_jar = match cookie_jar_id { - Some(id) => Some(get_cookie_jar(&window, id).await.expect("Failed to get cookie jar")), + Some(id) => Some(get_cookie_jar(&app_handle, id).await.expect("Failed to get cookie jar")), None => None, }; @@ -1102,44 +1115,59 @@ async fn cmd_send_http_request( } async fn response_err( + app_handle: &AppHandle, response: &HttpResponse, error: String, - w: &WebviewWindow, + update_source: &UpdateSource, ) -> HttpResponse { warn!("Failed to send request: {error:?}"); let mut response = response.clone(); response.state = HttpResponseState::Closed; response.error = Some(error.clone()); - response = update_response_if_id(w, &response, &UpdateSource::Window) + response = update_response_if_id(app_handle, &response, update_source) .await .expect("Failed to update response"); response } #[tauri::command] -async fn cmd_set_update_mode(update_mode: &str, w: WebviewWindow) -> Result { - cmd_set_key_value("app", "update_mode", update_mode, w).await.map_err(|e| e.to_string()) +async fn cmd_set_update_mode( + update_mode: &str, + app_handle: AppHandle, + window: WebviewWindow, +) -> YaakResult { + let (key_value, _created) = set_key_value_raw( + &app_handle, + "app", + "update_mode", + update_mode, + &UpdateSource::from_window(&window), + ) + .await; + Ok(key_value) } #[tauri::command] -async fn cmd_get_key_value( +async fn cmd_get_key_value( namespace: &str, key: &str, - w: WebviewWindow, + app_handle: AppHandle, ) -> Result, ()> { - let result = get_key_value_raw(&w, namespace, key).await; + let result = get_key_value_raw(&app_handle, namespace, key).await; Ok(result) } #[tauri::command] -async fn cmd_set_key_value( +async fn cmd_set_key_value( + app_handle: AppHandle, + window: WebviewWindow, namespace: &str, key: &str, value: &str, - w: WebviewWindow, ) -> Result { let (key_value, _created) = - set_key_value_raw(&w, namespace, key, value, &UpdateSource::Window).await; + set_key_value_raw(&app_handle, namespace, key, value, &UpdateSource::from_window(&window)) + .await; Ok(key_value) } @@ -1148,6 +1176,7 @@ async fn cmd_install_plugin( directory: &str, url: Option, plugin_manager: State<'_, PluginManager>, + app_handle: AppHandle, window: WebviewWindow, ) -> Result { plugin_manager @@ -1156,13 +1185,13 @@ async fn cmd_install_plugin( .map_err(|e| e.to_string())?; let plugin = upsert_plugin( - &window, + &app_handle, Plugin { directory: directory.into(), url, ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .map_err(|e| e.to_string())?; @@ -1175,8 +1204,9 @@ async fn cmd_uninstall_plugin( plugin_id: &str, plugin_manager: State<'_, PluginManager>, window: WebviewWindow, + app_handle: AppHandle, ) -> Result { - let plugin = delete_plugin(&window, plugin_id, &UpdateSource::Window) + let plugin = delete_plugin(&app_handle, plugin_id, &UpdateSource::from_window(&window)) .await .map_err(|e| e.to_string())?; @@ -1189,47 +1219,58 @@ async fn cmd_uninstall_plugin( } #[tauri::command] -async fn cmd_update_cookie_jar( +async fn cmd_update_cookie_jar( cookie_jar: CookieJar, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - upsert_cookie_jar(&w, &cookie_jar, &UpdateSource::Window).await.map_err(|e| e.to_string()) + upsert_cookie_jar(&app_handle, &cookie_jar, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_delete_cookie_jar(w: WebviewWindow, cookie_jar_id: &str) -> Result { - delete_cookie_jar(&w, cookie_jar_id, &UpdateSource::Window).await.map_err(|e| e.to_string()) +async fn cmd_delete_cookie_jar( + app_handle: AppHandle, + window: WebviewWindow, + cookie_jar_id: &str, +) -> Result { + delete_cookie_jar(&app_handle, cookie_jar_id, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_create_cookie_jar( +async fn cmd_create_cookie_jar( workspace_id: &str, name: &str, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { upsert_cookie_jar( - &w, + &app_handle, &CookieJar { name: name.to_string(), workspace_id: workspace_id.to_string(), ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_create_environment( +async fn cmd_create_environment( workspace_id: &str, environment_id: Option<&str>, name: &str, variables: Vec, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { upsert_environment( - &w, + &app_handle, Environment { workspace_id: workspace_id.to_string(), environment_id: environment_id.map(|s| s.to_string()), @@ -1237,22 +1278,23 @@ async fn cmd_create_environment( variables, ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_create_grpc_request( +async fn cmd_create_grpc_request( workspace_id: &str, name: &str, sort_priority: f32, folder_id: Option<&str>, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { upsert_grpc_request( - &w, + &app_handle, GrpcRequest { workspace_id: workspace_id.to_string(), name: name.to_string(), @@ -1260,184 +1302,240 @@ async fn cmd_create_grpc_request( sort_priority, ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_duplicate_grpc_request(id: &str, w: WebviewWindow) -> Result { - duplicate_grpc_request(&w, id, &UpdateSource::Window).await.map_err(|e| e.to_string()) +async fn cmd_duplicate_grpc_request( + id: &str, + app_handle: AppHandle, + window: WebviewWindow, +) -> Result { + duplicate_grpc_request(&app_handle, id, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] async fn cmd_duplicate_folder( + app_handle: AppHandle, window: WebviewWindow, id: &str, -) -> Result<(), String> { - let folder = get_folder(&window, id).await.map_err(|e| e.to_string())?; - duplicate_folder(&window, &folder).await.map_err(|e| e.to_string()) +) -> YaakResult<()> { + let folder = get_folder(&app_handle, id).await?; + let new_folder = + duplicate_folder(&app_handle, &folder, &UpdateSource::from_window(&window)).await?; + Ok(new_folder) } #[tauri::command] -async fn cmd_create_http_request( +async fn cmd_create_http_request( request: HttpRequest, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - upsert_http_request(&w, request, &UpdateSource::Window).await.map_err(|e| e.to_string()) + upsert_http_request(&app_handle, request, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_duplicate_http_request(id: &str, w: WebviewWindow) -> Result { - duplicate_http_request(&w, id, &UpdateSource::Window).await.map_err(|e| e.to_string()) +async fn cmd_duplicate_http_request( + id: &str, + app_handle: AppHandle, + window: WebviewWindow, +) -> Result { + duplicate_http_request(&app_handle, id, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_update_workspace(workspace: Workspace, w: WebviewWindow) -> Result { - upsert_workspace(&w, workspace, &UpdateSource::Window).await.map_err(|e| e.to_string()) +async fn cmd_update_workspace( + workspace: Workspace, + app_handle: AppHandle, + window: WebviewWindow, +) -> Result { + upsert_workspace(&app_handle, workspace, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_update_workspace_meta( +async fn cmd_update_workspace_meta( workspace_meta: WorkspaceMeta, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - upsert_workspace_meta(&w, workspace_meta, &UpdateSource::Window) + upsert_workspace_meta(&app_handle, workspace_meta, &UpdateSource::from_window(&window)) .await .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_update_environment( +async fn cmd_update_environment( environment: Environment, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - upsert_environment(&w, environment, &UpdateSource::Window).await.map_err(|e| e.to_string()) + upsert_environment(&app_handle, environment, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_update_grpc_request( +async fn cmd_update_grpc_request( request: GrpcRequest, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - upsert_grpc_request(&w, request, &UpdateSource::Window).await.map_err(|e| e.to_string()) + upsert_grpc_request(&app_handle, request, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_update_http_request( +async fn cmd_update_http_request( request: HttpRequest, - window: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - upsert_http_request(&window, request, &UpdateSource::Window).await.map_err(|e| e.to_string()) + upsert_http_request(&app_handle, request, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_delete_grpc_request( - w: WebviewWindow, +async fn cmd_delete_grpc_request( + app_handle: AppHandle, request_id: &str, + window: WebviewWindow, ) -> Result { - delete_grpc_request(&w, request_id, &UpdateSource::Window).await.map_err(|e| e.to_string()) + delete_grpc_request(&app_handle, request_id, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_delete_http_request( - w: WebviewWindow, +async fn cmd_delete_http_request( + app_handle: AppHandle, request_id: &str, + window: WebviewWindow, ) -> Result { - delete_http_request(&w, request_id, &UpdateSource::Window).await.map_err(|e| e.to_string()) + delete_http_request(&app_handle, request_id, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_list_folders(workspace_id: &str, w: WebviewWindow) -> Result, String> { - list_folders(&w, workspace_id).await.map_err(|e| e.to_string()) +async fn cmd_list_folders( + workspace_id: &str, + app_handle: AppHandle, +) -> Result, String> { + list_folders(&app_handle, workspace_id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_update_folder(folder: Folder, w: WebviewWindow) -> Result { - upsert_folder(&w, folder, &UpdateSource::Window).await.map_err(|e| e.to_string()) +async fn cmd_update_folder( + folder: Folder, + app_handle: AppHandle, + window: WebviewWindow, +) -> YaakResult { + Ok(upsert_folder(&app_handle, folder, &UpdateSource::from_window(&window)).await?) } #[tauri::command] -async fn cmd_delete_folder(w: WebviewWindow, folder_id: &str) -> Result { - delete_folder(&w, folder_id, &UpdateSource::Window).await.map_err(|e| e.to_string()) +async fn cmd_delete_folder( + app_handle: AppHandle, + window: WebviewWindow, + folder_id: &str, +) -> Result { + delete_folder(&app_handle, folder_id, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_delete_environment( - w: WebviewWindow, +async fn cmd_delete_environment( + app_handle: AppHandle, + window: WebviewWindow, environment_id: &str, ) -> Result { - delete_environment(&w, environment_id, &UpdateSource::Window).await.map_err(|e| e.to_string()) + delete_environment(&app_handle, environment_id, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_list_grpc_connections( +async fn cmd_list_grpc_connections( workspace_id: &str, - w: WebviewWindow, + app_handle: AppHandle, ) -> Result, String> { - list_grpc_connections_for_workspace(&w, workspace_id).await.map_err(|e| e.to_string()) + list_grpc_connections_for_workspace(&app_handle, workspace_id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_list_grpc_events( +async fn cmd_list_grpc_events( connection_id: &str, - w: WebviewWindow, + app_handle: AppHandle, ) -> Result, String> { - list_grpc_events(&w, connection_id).await.map_err(|e| e.to_string()) + list_grpc_events(&app_handle, connection_id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_list_grpc_requests( +async fn cmd_list_grpc_requests( workspace_id: &str, - w: WebviewWindow, + app_handle: AppHandle, ) -> Result, String> { - list_grpc_requests(&w, workspace_id).await.map_err(|e| e.to_string()) + list_grpc_requests(&app_handle, workspace_id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_list_http_requests( +async fn cmd_list_http_requests( workspace_id: &str, - w: WebviewWindow, + app_handle: AppHandle, ) -> Result, String> { - list_http_requests(&w, workspace_id).await.map_err(|e| e.to_string()) + list_http_requests(&app_handle, workspace_id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_list_environments( +async fn cmd_list_environments( workspace_id: &str, - w: WebviewWindow, + app_handle: AppHandle, ) -> Result, String> { // Not sure of a better place to put this... - ensure_base_environment(&w, workspace_id).await.map_err(|e| e.to_string())?; - - list_environments(&w, workspace_id).await.map_err(|e| e.to_string()) + ensure_base_environment(&app_handle, workspace_id).await.map_err(|e| e.to_string())?; + list_environments(&app_handle, workspace_id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_list_plugins(w: WebviewWindow) -> Result, String> { - list_plugins(&w).await.map_err(|e| e.to_string()) +async fn cmd_list_plugins(app_handle: AppHandle) -> Result, String> { + list_plugins(&app_handle).await.map_err(|e| e.to_string()) } #[tauri::command] async fn cmd_reload_plugins( + app_handle: AppHandle, window: WebviewWindow, plugin_manager: State<'_, PluginManager>, ) -> Result<(), String> { plugin_manager - .initialize_all_plugins(window.app_handle(), &WindowContext::from_window(&window)) + .initialize_all_plugins(&app_handle, &WindowContext::from_window(&window)) .await .map_err(|e| e.to_string())?; Ok(()) } #[tauri::command] -async fn cmd_plugin_info( +async fn cmd_plugin_info( id: &str, - w: WebviewWindow, + app_handle: AppHandle, plugin_manager: State<'_, PluginManager>, ) -> Result { - let plugin = get_plugin(&w, id).await.map_err(|e| e.to_string())?; + let plugin = get_plugin(&app_handle, id).await.map_err(|e| e.to_string())?; Ok(plugin_manager .get_plugin_by_dir(plugin.directory.as_str()) .await @@ -1447,51 +1545,68 @@ async fn cmd_plugin_info( } #[tauri::command] -async fn cmd_get_settings(w: WebviewWindow) -> Result { - Ok(get_or_create_settings(&w).await) +async fn cmd_get_settings(app_handle: AppHandle) -> Result { + Ok(get_or_create_settings(&app_handle).await) } #[tauri::command] -async fn cmd_update_settings(settings: Settings, w: WebviewWindow) -> Result { - update_settings(&w, settings, &UpdateSource::Window).await.map_err(|e| e.to_string()) +async fn cmd_update_settings( + settings: Settings, + app_handle: AppHandle, + window: WebviewWindow, +) -> Result { + update_settings(&app_handle, settings, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_get_folder(id: &str, w: WebviewWindow) -> Result { - get_folder(&w, id).await.map_err(|e| e.to_string()) +async fn cmd_get_folder(id: &str, app_handle: AppHandle) -> Result { + get_folder(&app_handle, id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_get_grpc_request(id: &str, w: WebviewWindow) -> Result, String> { - get_grpc_request(&w, id).await.map_err(|e| e.to_string()) +async fn cmd_get_grpc_request( + id: &str, + app_handle: AppHandle, +) -> Result, String> { + get_grpc_request(&app_handle, id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_get_http_request(id: &str, w: WebviewWindow) -> Result, String> { - get_http_request(&w, id).await.map_err(|e| e.to_string()) +async fn cmd_get_http_request( + id: &str, + app_handle: AppHandle, +) -> Result, String> { + get_http_request(&app_handle, id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_get_cookie_jar(id: &str, w: WebviewWindow) -> Result { - get_cookie_jar(&w, id).await.map_err(|e| e.to_string()) +async fn cmd_get_cookie_jar( + id: &str, + app_handle: AppHandle, +) -> Result { + get_cookie_jar(&app_handle, id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_list_cookie_jars( +async fn cmd_list_cookie_jars( workspace_id: &str, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result, String> { - let cookie_jars = list_cookie_jars(&w, workspace_id).await.expect("Failed to find cookie jars"); + let cookie_jars = + list_cookie_jars(&app_handle, workspace_id).await.expect("Failed to find cookie jars"); if cookie_jars.is_empty() { let cookie_jar = upsert_cookie_jar( - &w, + &app_handle, &CookieJar { name: "Default".to_string(), workspace_id: workspace_id.to_string(), ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .expect("Failed to create CookieJar"); @@ -1502,89 +1617,133 @@ async fn cmd_list_cookie_jars( } #[tauri::command] -async fn cmd_list_key_values(window: WebviewWindow) -> Result, String> { - list_key_values_raw(&window).await.map_err(|e| e.to_string()) +async fn cmd_list_key_values( + app_handle: AppHandle, +) -> Result, String> { + list_key_values_raw(&app_handle).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_get_environment(id: &str, window: WebviewWindow) -> Result { - get_environment(&window, id).await.map_err(|e| e.to_string()) +async fn cmd_get_environment( + id: &str, + app_handle: AppHandle, +) -> Result { + get_environment(&app_handle, id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_get_workspace(id: &str, window: WebviewWindow) -> Result { - get_workspace(&window, id).await.map_err(|e| e.to_string()) +async fn cmd_get_workspace( + id: &str, + app_handle: AppHandle, +) -> Result { + get_workspace(&app_handle, id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_list_http_responses( +async fn cmd_list_http_responses( workspace_id: &str, limit: Option, - window: WebviewWindow, + app_handle: AppHandle, ) -> Result, String> { - list_http_responses_for_workspace(&window, workspace_id, limit).await.map_err(|e| e.to_string()) + list_http_responses_for_workspace(&app_handle, workspace_id, limit) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_delete_http_response(id: &str, window: WebviewWindow) -> Result { - delete_http_response(&window, id, &UpdateSource::Window).await.map_err(|e| e.to_string()) +async fn cmd_delete_http_response( + id: &str, + app_handle: AppHandle, + window: WebviewWindow, +) -> Result { + delete_http_response(&app_handle, id, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_delete_grpc_connection( +async fn cmd_delete_grpc_connection( id: &str, - window: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - delete_grpc_connection(&window, id, &UpdateSource::Window).await.map_err(|e| e.to_string()) + delete_grpc_connection(&app_handle, id, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_delete_all_grpc_connections( +async fn cmd_delete_all_grpc_connections( request_id: &str, - window: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result<(), String> { - delete_all_grpc_connections(&window, request_id, &UpdateSource::Window) + delete_all_grpc_connections(&app_handle, request_id, &UpdateSource::from_window(&window)) .await .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_delete_send_history(workspace_id: &str, window: WebviewWindow) -> Result<(), String> { - delete_all_http_responses_for_workspace(&window, workspace_id, &UpdateSource::Window) - .await - .map_err(|e| e.to_string())?; - delete_all_grpc_connections_for_workspace(&window, workspace_id, &UpdateSource::Window) - .await - .map_err(|e| e.to_string())?; - delete_all_websocket_connections_for_workspace(&window, workspace_id, &UpdateSource::Window) - .await - .map_err(|e| e.to_string())?; +async fn cmd_delete_send_history( + workspace_id: &str, + app_handle: AppHandle, + window: WebviewWindow, +) -> Result<(), String> { + delete_all_http_responses_for_workspace( + &app_handle, + workspace_id, + &UpdateSource::from_window(&window), + ) + .await + .map_err(|e| e.to_string())?; + delete_all_grpc_connections_for_workspace( + &app_handle, + workspace_id, + &UpdateSource::from_window(&window), + ) + .await + .map_err(|e| e.to_string())?; + delete_all_websocket_connections_for_workspace( + &app_handle, + workspace_id, + &UpdateSource::from_window(&window), + ) + .await + .map_err(|e| e.to_string())?; Ok(()) } #[tauri::command] -async fn cmd_delete_all_http_responses( +async fn cmd_delete_all_http_responses( request_id: &str, - window: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result<(), String> { - delete_all_http_responses_for_request(&window, request_id, &UpdateSource::Window) - .await - .map_err(|e| e.to_string()) + delete_all_http_responses_for_request( + &app_handle, + request_id, + &UpdateSource::from_window(&window), + ) + .await + .map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_list_workspaces(window: WebviewWindow) -> Result, String> { - let workspaces = list_workspaces(&window).await.expect("Failed to find workspaces"); +async fn cmd_list_workspaces( + app_handle: AppHandle, + window: WebviewWindow, +) -> Result, String> { + let workspaces = list_workspaces(&app_handle).await.expect("Failed to find workspaces"); if workspaces.is_empty() { let workspace = upsert_workspace( - &window, + &app_handle, Workspace { name: "Yaak".to_string(), setting_follow_redirects: true, setting_validate_certificates: true, ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .expect("Failed to create Workspace"); @@ -1595,12 +1754,13 @@ async fn cmd_list_workspaces(window: WebviewWindow) -> Result, St } #[tauri::command] -async fn cmd_get_workspace_meta( - window: WebviewWindow, +async fn cmd_get_workspace_meta( + app_handle: AppHandle, + window: WebviewWindow, workspace_id: &str, ) -> Result { - let workspace = get_workspace(&window, workspace_id).await.map_err(|e| e.to_string())?; - get_or_create_workspace_meta(&window, &workspace, &UpdateSource::Window) + let workspace = get_workspace(&app_handle, workspace_id).await.map_err(|e| e.to_string())?; + get_or_create_workspace_meta(&app_handle, &workspace, &UpdateSource::from_window(&window)) .await .map_err(|e| e.to_string()) } @@ -1624,8 +1784,14 @@ async fn cmd_new_main_window(app_handle: AppHandle, url: &str) -> Result<(), Str } #[tauri::command] -async fn cmd_delete_workspace(w: WebviewWindow, workspace_id: &str) -> Result { - delete_workspace(&w, workspace_id, &UpdateSource::Window).await.map_err(|e| e.to_string()) +async fn cmd_delete_workspace( + app_handle: AppHandle, + window: WebviewWindow, + workspace_id: &str, +) -> Result { + delete_workspace(&app_handle, workspace_id, &UpdateSource::from_window(&window)) + .await + .map_err(|e| e.to_string()) } #[tauri::command] @@ -1808,8 +1974,9 @@ pub fn run() { match event { RunEvent::Ready => { let w = window::create_main_window(app_handle, "/"); + let h = app_handle.clone(); tauri::async_runtime::spawn(async move { - let info = history::store_launch_history(&w).await; + let info = history::store_launch_history(&h).await; debug!("Launched Yaak {:?}", info); }); @@ -1970,7 +2137,7 @@ fn workspace_id_from_window(window: &WebviewWindow) -> Option(window: &WebviewWindow) -> Option { match workspace_id_from_window(&window) { None => None, - Some(id) => get_workspace(window, id.as_str()).await.ok(), + Some(id) => get_workspace(window.app_handle(), id.as_str()).await.ok(), } } @@ -1983,7 +2150,7 @@ fn environment_id_from_window(window: &WebviewWindow) -> Option(window: &WebviewWindow) -> Option { match environment_id_from_window(&window) { None => None, - Some(id) => get_environment(window, id.as_str()).await.ok(), + Some(id) => get_environment(window.app_handle(), id.as_str()).await.ok(), } } @@ -1996,6 +2163,6 @@ fn cookie_jar_id_from_window(window: &WebviewWindow) -> Option(window: &WebviewWindow) -> Option { match cookie_jar_id_from_window(&window) { None => None, - Some(id) => get_cookie_jar(window, id.as_str()).await.ok(), + Some(id) => get_cookie_jar(window.app_handle(), id.as_str()).await.ok(), } } diff --git a/src-tauri/src/notifications.rs b/src-tauri/src/notifications.rs index 470c06da8..fc4a94a73 100644 --- a/src-tauri/src/notifications.rs +++ b/src-tauri/src/notifications.rs @@ -6,7 +6,7 @@ use log::debug; use reqwest::Method; use serde::{Deserialize, Serialize}; use serde_json::Value; -use tauri::{Emitter, Manager, Runtime, WebviewWindow}; +use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow}; use yaak_models::queries::{get_key_value_raw, set_key_value_raw, UpdateSource}; // Check for updates every hour @@ -43,16 +43,18 @@ impl YaakNotifier { } } - pub async fn seen(&mut self, w: &WebviewWindow, id: &str) -> Result<(), String> { - let mut seen = get_kv(w).await?; + pub async fn seen(&mut self, window: &WebviewWindow, id: &str) -> Result<(), String> { + let app_handle = window.app_handle(); + let mut seen = get_kv(app_handle).await?; seen.push(id.to_string()); debug!("Marked notification as seen {}", id); let seen_json = serde_json::to_string(&seen).map_err(|e| e.to_string())?; - set_key_value_raw(w, KV_NAMESPACE, KV_KEY, seen_json.as_str(), &UpdateSource::Window).await; + set_key_value_raw(app_handle, KV_NAMESPACE, KV_KEY, seen_json.as_str(), &UpdateSource::from_window(window)).await; Ok(()) } pub async fn check(&mut self, window: &WebviewWindow) -> Result<(), String> { + let app_handle = window.app_handle(); let ignore_check = self.last_check.elapsed().unwrap().as_secs() < MAX_UPDATE_CHECK_SECONDS; if ignore_check { @@ -61,8 +63,8 @@ impl YaakNotifier { self.last_check = SystemTime::now(); - let num_launches = get_num_launches(window).await; - let info = window.app_handle().package_info().clone(); + let num_launches = get_num_launches(app_handle).await; + let info = app_handle.package_info().clone(); let req = reqwest::Client::default() .request(Method::GET, "https://notify.yaak.app/notifications") .query(&[ @@ -90,14 +92,14 @@ impl YaakNotifier { for notification in notifications { let age = notification.timestamp.signed_duration_since(Utc::now()); - let seen = get_kv(window).await?; + let seen = get_kv(app_handle).await?; if seen.contains(¬ification.id) || (age > Duration::days(2)) { debug!("Already seen notification {}", notification.id); continue; } debug!("Got notification {:?}", notification); - let _ = window.emit_to(window.label(), "notification", notification.clone()); + let _ = app_handle.emit_to(window.label(), "notification", notification.clone()); break; // Only show one notification } @@ -105,8 +107,8 @@ impl YaakNotifier { } } -async fn get_kv(w: &WebviewWindow) -> Result, String> { - match get_key_value_raw(w, "notifications", "seen").await { +async fn get_kv(app_handle: &AppHandle) -> Result, String> { + match get_key_value_raw(app_handle, "notifications", "seen").await { None => Ok(Vec::new()), Some(v) => serde_json::from_str(&v.value).map_err(|e| e.to_string()), } diff --git a/src-tauri/src/plugin_events.rs b/src-tauri/src/plugin_events.rs index c4f203ab3..8da381c30 100644 --- a/src-tauri/src/plugin_events.rs +++ b/src-tauri/src/plugin_events.rs @@ -18,8 +18,8 @@ use yaak_models::queries::{ use yaak_plugins::events::{ Color, DeleteKeyValueResponse, EmptyPayload, FindHttpResponsesResponse, GetHttpRequestByIdResponse, GetKeyValueResponse, Icon, InternalEvent, InternalEventPayload, - RenderHttpRequestResponse, SendHttpRequestResponse, SetKeyValueResponse, ShowToastRequest, - TemplateRenderResponse, WindowContext, WindowNavigateEvent, + RenderHttpRequestResponse, RenderPurpose, SendHttpRequestResponse, SetKeyValueResponse, + ShowToastRequest, TemplateRenderResponse, WindowContext, WindowNavigateEvent, }; use yaak_plugins::manager::PluginManager; use yaak_plugins::plugin_handle::PluginHandle; @@ -80,7 +80,7 @@ pub(crate) async fn handle_plugin_event( .await .expect("Failed to get workspace_id from window URL"); let environment = environment_from_window(&window).await; - let base_environment = get_base_environment(&window, workspace.id.as_str()) + let base_environment = get_base_environment(app_handle, workspace.id.as_str()) .await .expect("Failed to get base environment"); let cb = PluginTemplateCallback::new(app_handle, &window_context, req.purpose); @@ -104,7 +104,7 @@ pub(crate) async fn handle_plugin_event( .await .expect("Failed to get workspace_id from window URL"); let environment = environment_from_window(&window).await; - let base_environment = get_base_environment(&window, workspace.id.as_str()) + let base_environment = get_base_environment(app_handle, workspace.id.as_str()) .await .expect("Failed to get base environment"); let cb = PluginTemplateCallback::new(app_handle, &window_context, req.purpose); @@ -145,7 +145,7 @@ pub(crate) async fn handle_plugin_event( updated_at: Utc::now().naive_utc(), // TODO: Add reloaded_at field to use instead ..plugin }; - upsert_plugin(&window, new_plugin, &UpdateSource::Plugin).await.unwrap(); + upsert_plugin(app_handle, new_plugin, &UpdateSource::Plugin).await.unwrap(); } let toast_event = plugin_handle.build_event_to_send( &WindowContext::from_window(&window), @@ -177,7 +177,7 @@ pub(crate) async fn handle_plugin_event( HttpResponse::new() } else { create_default_http_response( - &window, + app_handle, http_request.id.as_str(), &UpdateSource::Plugin, ) diff --git a/src-tauri/yaak-license/src/license.rs b/src-tauri/yaak-license/src/license.rs index f24003b34..e5b2b8efd 100644 --- a/src-tauri/yaak-license/src/license.rs +++ b/src-tauri/yaak-license/src/license.rs @@ -81,11 +81,11 @@ pub async fn activate_license( let body: ActivateLicenseResponsePayload = response.json().await?; yaak_models::queries::set_key_value_string( - window, + window.app_handle(), KV_ACTIVATION_ID_KEY, KV_NAMESPACE, body.activation_id.as_str(), - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await; @@ -100,7 +100,8 @@ pub async fn deactivate_license( window: &WebviewWindow, p: DeactivateLicenseRequestPayload, ) -> Result<()> { - let activation_id = get_activation_id(window).await; + let app_handle = window.app_handle(); + let activation_id = get_activation_id(app_handle).await; let client = reqwest::Client::new(); let path = format!("/licenses/activations/{}/deactivate", activation_id); @@ -119,14 +120,14 @@ pub async fn deactivate_license( } yaak_models::queries::delete_key_value( - window, + app_handle, KV_ACTIVATION_ID_KEY, KV_NAMESPACE, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await; - if let Err(e) = window.emit("license-deactivated", true) { + if let Err(e) = app_handle.emit("license-deactivated", true) { warn!("Failed to emit deactivate-license event: {}", e); } @@ -143,7 +144,10 @@ pub enum LicenseCheckStatus { Trialing { end: NaiveDateTime }, } -pub async fn check_license(app_handle: &AppHandle, payload: CheckActivationRequestPayload) -> Result { +pub async fn check_license( + app_handle: &AppHandle, + payload: CheckActivationRequestPayload, +) -> Result { let activation_id = get_activation_id(app_handle).await; let settings = yaak_models::queries::get_or_create_settings(app_handle).await; let trial_end = settings.created_at.add(Duration::from_secs(TRIAL_SECONDS)); @@ -195,7 +199,7 @@ fn build_url(path: &str) -> String { } } -pub async fn get_activation_id(mgr: &impl Manager) -> String { - yaak_models::queries::get_key_value_string(mgr, KV_ACTIVATION_ID_KEY, KV_NAMESPACE, "") +pub async fn get_activation_id(app_handle: &AppHandle) -> String { + yaak_models::queries::get_key_value_string(app_handle, KV_ACTIVATION_ID_KEY, KV_NAMESPACE, "") .await } diff --git a/src-tauri/yaak-models/bindings/gen_models.ts b/src-tauri/yaak-models/bindings/gen_models.ts index 53b4618ed..c42af1e8d 100644 --- a/src-tauri/yaak-models/bindings/gen_models.ts +++ b/src-tauri/yaak-models/bindings/gen_models.ts @@ -44,7 +44,7 @@ export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, export type KeyValue = { model: "key_value", createdAt: string, updatedAt: string, key: string, namespace: string, value: string, }; -export type ModelPayload = { model: AnyModel, windowLabel: string, updateSource: UpdateSource, }; +export type ModelPayload = { model: AnyModel, updateSource: UpdateSource, }; export type Plugin = { model: "plugin", id: string, createdAt: string, updatedAt: string, checkedAt: string | null, directory: string, enabled: boolean, url: string | null, }; @@ -60,7 +60,7 @@ export type SyncHistory = { model: "sync_history", id: string, workspaceId: stri export type SyncState = { model: "sync_state", id: string, workspaceId: string, createdAt: string, updatedAt: string, flushedAt: string, modelId: string, checksum: string, relPath: string, syncDir: string, }; -export type UpdateSource = "sync" | "window" | "plugin" | "background" | "import"; +export type UpdateSource = { "type": "sync" } | { "type": "window", label: string, } | { "type": "plugin" } | { "type": "background" } | { "type": "import" }; export type WebsocketConnection = { model: "websocket_connection", id: string, createdAt: string, updatedAt: string, workspaceId: string, requestId: string, elapsed: number, error: string | null, headers: Array, state: WebsocketConnectionState, status: number, url: string, }; diff --git a/src-tauri/yaak-models/src/error.rs b/src-tauri/yaak-models/src/error.rs index 9f0fb0ca7..27f693f92 100644 --- a/src-tauri/yaak-models/src/error.rs +++ b/src-tauri/yaak-models/src/error.rs @@ -4,10 +4,16 @@ use thiserror::Error; pub enum Error { #[error("SQL error: {0}")] SqlError(#[from] rusqlite::Error), + + #[error("SQL Pool error: {0}")] + SqlPoolError(#[from] r2d2::Error), + #[error("JSON error: {0}")] JsonError(#[from] serde_json::Error), + #[error("Model not found {0}")] ModelNotFound(String), + #[error("unknown error")] Unknown, } diff --git a/src-tauri/yaak-models/src/lib.rs b/src-tauri/yaak-models/src/lib.rs index bcb66425c..1b4b1ee7b 100644 --- a/src-tauri/yaak-models/src/lib.rs +++ b/src-tauri/yaak-models/src/lib.rs @@ -4,3 +4,4 @@ pub mod queries; pub mod plugin; pub mod render; +pub mod manager; diff --git a/src-tauri/yaak-models/src/manager.rs b/src-tauri/yaak-models/src/manager.rs new file mode 100644 index 000000000..4da711611 --- /dev/null +++ b/src-tauri/yaak-models/src/manager.rs @@ -0,0 +1,40 @@ +use crate::error::Result; +use crate::models::{Workspace, WorkspaceIden}; +use crate::plugin::SqliteConnection; +use r2d2::{Pool, PooledConnection}; +use r2d2_sqlite::SqliteConnectionManager; +use rusqlite::Connection; +use sea_query::{Asterisk, Order, Query, SqliteQueryBuilder}; +use sea_query_rusqlite::RusqliteBinder; +use std::future::Future; +use std::ops::Deref; +use tauri::{AppHandle, Manager, Runtime}; + +pub struct QueryManager { + pool: Pool, +} + +pub trait DBConnection { + fn connect( + &self, + ) -> impl Future>> + Send; +} + +impl DBConnection for AppHandle { + async fn connect(&self) -> Result> { + let dbm = &*self.state::(); + let db = dbm.0.lock().await.get()?; + Ok(db) + } +} + +pub async fn list_workspaces>(c: &T) -> Result> { + let (sql, params) = Query::select() + .from(WorkspaceIden::Table) + .column(Asterisk) + .order_by(WorkspaceIden::Name, Order::Asc) + .build_rusqlite(SqliteQueryBuilder); + let mut stmt = c.prepare(sql.as_str())?; + let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; + Ok(items.map(|v| v.unwrap()).collect()) +} diff --git a/src-tauri/yaak-models/src/queries.rs b/src-tauri/yaak-models/src/queries.rs index 8c6b1ddfc..71210bbc2 100644 --- a/src-tauri/yaak-models/src/queries.rs +++ b/src-tauri/yaak-models/src/queries.rs @@ -28,34 +28,34 @@ use ts_rs::TS; const MAX_HISTORY_ITEMS: usize = 20; pub async fn set_key_value_string( - mgr: &WebviewWindow, + app_handle: &AppHandle, namespace: &str, key: &str, value: &str, update_source: &UpdateSource, ) -> (KeyValue, bool) { let encoded = serde_json::to_string(value); - set_key_value_raw(mgr, namespace, key, &encoded.unwrap(), update_source).await + set_key_value_raw(app_handle, namespace, key, &encoded.unwrap(), update_source).await } pub async fn set_key_value_int( - mgr: &WebviewWindow, + app_handle: &AppHandle, namespace: &str, key: &str, value: i32, update_source: &UpdateSource, ) -> (KeyValue, bool) { let encoded = serde_json::to_string(&value); - set_key_value_raw(mgr, namespace, key, &encoded.unwrap(), update_source).await + set_key_value_raw(app_handle, namespace, key, &encoded.unwrap(), update_source).await } pub async fn get_key_value_string( - mgr: &impl Manager, + app_handle: &AppHandle, namespace: &str, key: &str, default: &str, ) -> String { - match get_key_value_raw(mgr, namespace, key).await { + match get_key_value_raw(app_handle, namespace, key).await { None => default.to_string(), Some(v) => { let result = serde_json::from_str(&v.value); @@ -71,12 +71,12 @@ pub async fn get_key_value_string( } pub async fn get_key_value_int( - mgr: &impl Manager, + app_handle: &AppHandle, namespace: &str, key: &str, default: i32, ) -> i32 { - match get_key_value_raw(mgr, namespace, key).await { + match get_key_value_raw(app_handle, namespace, key).await { None => default.clone(), Some(v) => { let result = serde_json::from_str(&v.value); @@ -92,15 +92,15 @@ pub async fn get_key_value_int( } pub async fn set_key_value_raw( - w: &WebviewWindow, + app_handle: &AppHandle, namespace: &str, key: &str, value: &str, update_source: &UpdateSource, ) -> (KeyValue, bool) { - let existing = get_key_value_raw(w, namespace, key).await; + let existing = get_key_value_raw(app_handle, namespace, key).await; - let dbm = &*w.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() .into_table(KeyValueIden::Table) @@ -130,22 +130,22 @@ pub async fn set_key_value_raw( let m: KeyValue = stmt .query_row(&*params.as_params(), |row| row.try_into()) .expect("Failed to upsert KeyValue"); - emit_upserted_model(w, &AnyModel::KeyValue(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::KeyValue(m.to_owned()), update_source); (m, existing.is_none()) } pub async fn delete_key_value( - w: &WebviewWindow, + app_handle: &AppHandle, namespace: &str, key: &str, update_source: &UpdateSource, ) { - let kv = match get_key_value_raw(w, namespace, key).await { + let kv = match get_key_value_raw(app_handle, namespace, key).await { None => return, Some(m) => m, }; - let dbm = &*w.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() .from_table(KeyValueIden::Table) @@ -156,11 +156,11 @@ pub async fn delete_key_value( ) .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params()).expect("Failed to delete PluginKeyValue"); - emit_deleted_model(w, &AnyModel::KeyValue(kv.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::KeyValue(kv.to_owned()), update_source); } -pub async fn list_key_values_raw(mgr: &impl Manager) -> Result> { - let dbm = &*mgr.state::(); +pub async fn list_key_values_raw(app_handle: &AppHandle) -> Result> { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(KeyValueIden::Table) @@ -172,11 +172,11 @@ pub async fn list_key_values_raw(mgr: &impl Manager) -> Result( - mgr: &impl Manager, + app_handle: &AppHandle, namespace: &str, key: &str, ) -> Option { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(KeyValueIden::Table) @@ -192,11 +192,11 @@ pub async fn get_key_value_raw( } pub async fn get_plugin_key_value( - mgr: &impl Manager, + app_handle: &AppHandle, plugin_name: &str, key: &str, ) -> Option { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(PluginKeyValueIden::Table) @@ -212,14 +212,14 @@ pub async fn get_plugin_key_value( } pub async fn set_plugin_key_value( - mgr: &impl Manager, + app_handle: &AppHandle, plugin_name: &str, key: &str, value: &str, ) -> (PluginKeyValue, bool) { - let existing = get_plugin_key_value(mgr, plugin_name, key).await; + let existing = get_plugin_key_value(app_handle, plugin_name, key).await; - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() .into_table(PluginKeyValueIden::Table) @@ -253,15 +253,15 @@ pub async fn set_plugin_key_value( } pub async fn delete_plugin_key_value( - mgr: &impl Manager, + app_handle: &AppHandle, plugin_name: &str, key: &str, ) -> bool { - if let None = get_plugin_key_value(mgr, plugin_name, key).await { + if let None = get_plugin_key_value(app_handle, plugin_name, key).await { return false; } - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() .from_table(PluginKeyValueIden::Table) @@ -271,12 +271,13 @@ pub async fn delete_plugin_key_value( .add(Expr::col(PluginKeyValueIden::Key).eq(key)), ) .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params()).expect("Failed to delete PluginKeyValue"); + let mut stmt = db.prepare(sql.as_str()).unwrap(); + stmt.execute(&*params.as_params()).expect("Failed to delete PluginKeyValue"); true } -pub async fn list_workspaces(mgr: &impl Manager) -> Result> { - let dbm = &*mgr.state::(); +pub async fn list_workspaces(app_handle: &AppHandle) -> Result> { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(WorkspaceIden::Table) @@ -288,8 +289,10 @@ pub async fn list_workspaces(mgr: &impl Manager) -> Result(mgr: &impl Manager) -> Result> { - let dbm = &*mgr.state::(); +pub async fn list_workspace_metas( + app_handle: &AppHandle, +) -> Result> { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(WorkspaceMetaIden::Table) @@ -300,8 +303,8 @@ pub async fn list_workspace_metas(mgr: &impl Manager) -> Result(mgr: &impl Manager, id: &str) -> Result { - let dbm = &*mgr.state::(); +pub async fn get_workspace(app_handle: &AppHandle, id: &str) -> Result { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(WorkspaceIden::Table) @@ -313,10 +316,10 @@ pub async fn get_workspace(mgr: &impl Manager, id: &str) -> Resul } pub async fn get_workspace_meta( - mgr: &impl Manager, + app_handle: &AppHandle, workspace: &Workspace, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(WorkspaceMetaIden::Table) @@ -328,17 +331,17 @@ pub async fn get_workspace_meta( } pub async fn get_or_create_workspace_meta( - window: &WebviewWindow, + app_handle: &AppHandle, workspace: &Workspace, update_source: &UpdateSource, ) -> Result { - let workspace_meta = get_workspace_meta(window, workspace).await?; + let workspace_meta = get_workspace_meta(app_handle, workspace).await?; if let Some(m) = workspace_meta { return Ok(m); } upsert_workspace_meta( - window, + app_handle, WorkspaceMeta { workspace_id: workspace.to_owned().id, ..Default::default() @@ -348,8 +351,8 @@ pub async fn get_or_create_workspace_meta( .await } -pub async fn exists_workspace(mgr: &impl Manager, id: &str) -> Result { - let dbm = &*mgr.state::(); +pub async fn exists_workspace(app_handle: &AppHandle, id: &str) -> Result { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(WorkspaceIden::Table) @@ -361,7 +364,7 @@ pub async fn exists_workspace(mgr: &impl Manager, id: &str) -> Re } pub async fn upsert_workspace( - window: &WebviewWindow, + app_handle: &AppHandle, workspace: Workspace, update_source: &UpdateSource, ) -> Result { @@ -371,7 +374,7 @@ pub async fn upsert_workspace( }; let trimmed_name = workspace.name.trim(); - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() @@ -415,12 +418,12 @@ pub async fn upsert_workspace( let mut stmt = db.prepare(&sql)?; let m: Workspace = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::Workspace(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::Workspace(m.to_owned()), update_source); Ok(m) } pub async fn upsert_workspace_meta( - window: &WebviewWindow, + app_handle: &AppHandle, workspace_meta: WorkspaceMeta, update_source: &UpdateSource, ) -> Result { @@ -429,7 +432,7 @@ pub async fn upsert_workspace_meta( _ => workspace_meta.id.to_string(), }; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() @@ -461,18 +464,18 @@ pub async fn upsert_workspace_meta( let mut stmt = db.prepare(&sql)?; let m: WorkspaceMeta = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::WorkspaceMeta(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::WorkspaceMeta(m.to_owned()), update_source); Ok(m) } pub async fn delete_workspace( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let workspace = get_workspace(window, id).await?; + let workspace = get_workspace(app_handle, id).await?; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() @@ -481,16 +484,16 @@ pub async fn delete_workspace( .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params())?; - for r in list_responses_by_workspace_id(window, id).await? { - delete_http_response(window, &r.id, update_source).await?; + for r in list_responses_by_workspace_id(app_handle, id).await? { + delete_http_response(app_handle, &r.id, update_source).await?; } - emit_deleted_model(window, &AnyModel::Workspace(workspace.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::Workspace(workspace.to_owned()), update_source); Ok(workspace) } -pub async fn get_cookie_jar(mgr: &impl Manager, id: &str) -> Result { - let dbm = &*mgr.state::(); +pub async fn get_cookie_jar(app_handle: &AppHandle, id: &str) -> Result { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -503,10 +506,10 @@ pub async fn get_cookie_jar(mgr: &impl Manager, id: &str) -> Resu } pub async fn list_cookie_jars( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(CookieJarIden::Table) @@ -519,12 +522,12 @@ pub async fn list_cookie_jars( } pub async fn delete_cookie_jar( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let cookie_jar = get_cookie_jar(window, id).await?; - let dbm = &*window.app_handle().state::(); + let cookie_jar = get_cookie_jar(app_handle, id).await?; + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() @@ -533,16 +536,16 @@ pub async fn delete_cookie_jar( .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(window, &AnyModel::CookieJar(cookie_jar.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::CookieJar(cookie_jar.to_owned()), update_source); Ok(cookie_jar) } pub async fn duplicate_grpc_request( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let mut request = match get_grpc_request(window, id).await? { + let mut request = match get_grpc_request(app_handle, id).await? { Some(r) => r, None => { return Err(ModelNotFound(id.to_string())); @@ -550,22 +553,22 @@ pub async fn duplicate_grpc_request( }; request.sort_priority = request.sort_priority + 0.001; request.id = "".to_string(); - upsert_grpc_request(window, request, update_source).await + upsert_grpc_request(app_handle, request, update_source).await } pub async fn delete_grpc_request( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let grpc_request = match get_grpc_request(window, id).await? { + let grpc_request = match get_grpc_request(app_handle, id).await? { Some(r) => r, None => { return Err(ModelNotFound(id.to_string())); } }; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() .from_table(GrpcRequestIden::Table) @@ -573,12 +576,12 @@ pub async fn delete_grpc_request( .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(window, &AnyModel::GrpcRequest(grpc_request.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::GrpcRequest(grpc_request.to_owned()), update_source); Ok(grpc_request) } pub async fn upsert_grpc_request( - window: &WebviewWindow, + app_handle: &AppHandle, request: GrpcRequest, update_source: &UpdateSource, ) -> Result { @@ -588,7 +591,7 @@ pub async fn upsert_grpc_request( }; let trimmed_name = request.name.trim(); - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() .into_table(GrpcRequestIden::Table) @@ -650,15 +653,15 @@ pub async fn upsert_grpc_request( let mut stmt = db.prepare(sql.as_str())?; let m: GrpcRequest = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::GrpcRequest(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::GrpcRequest(m.to_owned()), update_source); Ok(m) } pub async fn get_grpc_request( - mgr: &impl Manager, + app_handle: &AppHandle, id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -671,10 +674,10 @@ pub async fn get_grpc_request( } pub async fn list_grpc_requests( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(GrpcRequestIden::Table) @@ -687,22 +690,22 @@ pub async fn list_grpc_requests( } pub async fn upsert_grpc_connection( - window: &WebviewWindow, + app_handle: &AppHandle, connection: &GrpcConnection, update_source: &UpdateSource, ) -> Result { let connections = - list_grpc_connections_for_request(window, connection.request_id.as_str()).await?; + list_grpc_connections_for_request(app_handle, connection.request_id.as_str()).await?; for c in connections.iter().skip(MAX_HISTORY_ITEMS - 1) { debug!("Deleting old grpc connection {}", c.id); - delete_grpc_connection(window, c.id.as_str(), update_source).await?; + delete_grpc_connection(app_handle, c.id.as_str(), update_source).await?; } let id = match connection.id.as_str() { "" => generate_model_id(ModelType::TypeGrpcConnection), _ => connection.id.to_string(), }; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() .into_table(GrpcConnectionIden::Table) @@ -756,15 +759,15 @@ pub async fn upsert_grpc_connection( let mut stmt = db.prepare(sql.as_str())?; let m: GrpcConnection = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::GrpcConnection(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::GrpcConnection(m.to_owned()), update_source); Ok(m) } pub async fn get_grpc_connection( - mgr: &impl Manager, + app_handle: &AppHandle, id: &str, ) -> Result { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(GrpcConnectionIden::Table) @@ -776,10 +779,10 @@ pub async fn get_grpc_connection( } pub async fn list_grpc_connections_for_workspace( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -794,10 +797,10 @@ pub async fn list_grpc_connections_for_workspace( } pub async fn list_grpc_connections_for_request( - mgr: &impl Manager, + app_handle: &AppHandle, request_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -812,13 +815,13 @@ pub async fn list_grpc_connections_for_request( } pub async fn delete_grpc_connection( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let m = get_grpc_connection(window, id).await?; + let m = get_grpc_connection(app_handle, id).await?; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() @@ -827,34 +830,34 @@ pub async fn delete_grpc_connection( .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(window, &AnyModel::GrpcConnection(m.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::GrpcConnection(m.to_owned()), update_source); Ok(m) } pub async fn delete_all_grpc_connections( - window: &WebviewWindow, + app_handle: &AppHandle, request_id: &str, update_source: &UpdateSource, ) -> Result<()> { - for r in list_grpc_connections_for_request(window, request_id).await? { - delete_grpc_connection(window, &r.id, update_source).await?; + for r in list_grpc_connections_for_request(app_handle, request_id).await? { + delete_grpc_connection(app_handle, &r.id, update_source).await?; } Ok(()) } pub async fn delete_all_grpc_connections_for_workspace( - window: &WebviewWindow, + app_handle: &AppHandle, workspace_id: &str, update_source: &UpdateSource, ) -> Result<()> { - for r in list_grpc_connections_for_workspace(window, workspace_id).await? { - delete_grpc_connection(window, &r.id, update_source).await?; + for r in list_grpc_connections_for_workspace(app_handle, workspace_id).await? { + delete_grpc_connection(app_handle, &r.id, update_source).await?; } Ok(()) } pub async fn upsert_grpc_event( - window: &WebviewWindow, + app_handle: &AppHandle, event: &GrpcEvent, update_source: &UpdateSource, ) -> Result { @@ -863,7 +866,7 @@ pub async fn upsert_grpc_event( _ => event.id.to_string(), }; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() .into_table(GrpcEventIden::Table) @@ -910,12 +913,12 @@ pub async fn upsert_grpc_event( let mut stmt = db.prepare(sql.as_str())?; let m: GrpcEvent = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::GrpcEvent(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::GrpcEvent(m.to_owned()), update_source); Ok(m) } -pub async fn get_grpc_event(mgr: &impl Manager, id: &str) -> Result { - let dbm = &*mgr.state::(); +pub async fn get_grpc_event(app_handle: &AppHandle, id: &str) -> Result { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(GrpcEventIden::Table) @@ -927,10 +930,10 @@ pub async fn get_grpc_event(mgr: &impl Manager, id: &str) -> Resu } pub async fn list_grpc_events( - mgr: &impl Manager, + app_handle: &AppHandle, connection_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -945,18 +948,18 @@ pub async fn list_grpc_events( } pub async fn delete_websocket_request( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let request = match get_websocket_request(window, id).await? { + let request = match get_websocket_request(app_handle, id).await? { Some(r) => r, None => { return Err(ModelNotFound(id.to_string())); } }; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() .from_table(WebsocketRequestIden::Table) @@ -964,18 +967,18 @@ pub async fn delete_websocket_request( .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(window, &AnyModel::WebsocketRequest(request.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::WebsocketRequest(request.to_owned()), update_source); Ok(request) } pub async fn delete_websocket_connection( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let m = get_websocket_connection(window, id).await?; + let m = get_websocket_connection(app_handle, id).await?; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() .from_table(WebsocketConnectionIden::Table) @@ -983,37 +986,37 @@ pub async fn delete_websocket_connection( .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(window, &AnyModel::WebsocketConnection(m.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::WebsocketConnection(m.to_owned()), update_source); Ok(m) } pub async fn delete_all_websocket_connections( - window: &WebviewWindow, + app_handle: &AppHandle, request_id: &str, update_source: &UpdateSource, ) -> Result<()> { - for c in list_websocket_connections_for_request(window, request_id).await? { - delete_websocket_connection(window, &c.id, update_source).await?; + for c in list_websocket_connections_for_request(app_handle, request_id).await? { + delete_websocket_connection(app_handle, &c.id, update_source).await?; } Ok(()) } pub async fn delete_all_websocket_connections_for_workspace( - window: &WebviewWindow, + app_handle: &AppHandle, workspace_id: &str, update_source: &UpdateSource, ) -> Result<()> { - for c in list_websocket_connections_for_workspace(window, workspace_id).await? { - delete_websocket_connection(window, &c.id, update_source).await?; + for c in list_websocket_connections_for_workspace(app_handle, workspace_id).await? { + delete_websocket_connection(app_handle, &c.id, update_source).await?; } Ok(()) } pub async fn get_websocket_connection( - mgr: &impl Manager, + app_handle: &AppHandle, id: &str, ) -> Result { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(WebsocketConnectionIden::Table) @@ -1025,7 +1028,7 @@ pub async fn get_websocket_connection( } pub async fn upsert_websocket_event( - window: &WebviewWindow, + app_handle: &AppHandle, event: WebsocketEvent, update_source: &UpdateSource, ) -> Result { @@ -1034,7 +1037,7 @@ pub async fn upsert_websocket_event( _ => event.id.to_string(), }; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() .into_table(WebsocketEventIden::Table) @@ -1075,26 +1078,26 @@ pub async fn upsert_websocket_event( let mut stmt = db.prepare(sql.as_str())?; let m: WebsocketEvent = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::WebsocketEvent(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::WebsocketEvent(m.to_owned()), update_source); Ok(m) } pub async fn duplicate_websocket_request( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let mut request = match get_websocket_request(window, id).await? { + let mut request = match get_websocket_request(app_handle, id).await? { None => return Err(ModelNotFound(id.to_string())), Some(r) => r, }; request.id = "".to_string(); request.sort_priority = request.sort_priority + 0.001; - upsert_websocket_request(window, request, update_source).await + upsert_websocket_request(app_handle, request, update_source).await } pub async fn upsert_websocket_request( - window: &WebviewWindow, + app_handle: &AppHandle, request: WebsocketRequest, update_source: &UpdateSource, ) -> Result { @@ -1104,7 +1107,7 @@ pub async fn upsert_websocket_request( }; let trimmed_name = request.name.trim(); - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() .into_table(WebsocketRequestIden::Table) @@ -1163,15 +1166,15 @@ pub async fn upsert_websocket_request( let mut stmt = db.prepare(sql.as_str())?; let m: WebsocketRequest = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::WebsocketRequest(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::WebsocketRequest(m.to_owned()), update_source); Ok(m) } pub async fn list_websocket_connections_for_workspace( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -1186,10 +1189,10 @@ pub async fn list_websocket_connections_for_workspace( } pub async fn list_websocket_connections_for_request( - mgr: &impl Manager, + app_handle: &AppHandle, request_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -1204,22 +1207,22 @@ pub async fn list_websocket_connections_for_request( } pub async fn upsert_websocket_connection( - window: &WebviewWindow, + app_handle: &AppHandle, connection: &WebsocketConnection, update_source: &UpdateSource, ) -> Result { let connections = - list_websocket_connections_for_request(window, connection.request_id.as_str()).await?; + list_websocket_connections_for_request(app_handle, connection.request_id.as_str()).await?; for c in connections.iter().skip(MAX_HISTORY_ITEMS - 1) { debug!("Deleting old websocket connection {}", c.id); - delete_websocket_connection(window, c.id.as_str(), update_source).await?; + delete_websocket_connection(app_handle, c.id.as_str(), update_source).await?; } let id = match connection.id.as_str() { "" => generate_model_id(ModelType::TypeWebSocketConnection), _ => connection.id.to_string(), }; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() .into_table(WebsocketConnectionIden::Table) @@ -1267,15 +1270,15 @@ pub async fn upsert_websocket_connection( let mut stmt = db.prepare(sql.as_str())?; let m: WebsocketConnection = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::WebsocketConnection(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::WebsocketConnection(m.to_owned()), update_source); Ok(m) } pub async fn get_websocket_request( - mgr: &impl Manager, + app_handle: &AppHandle, id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -1288,10 +1291,10 @@ pub async fn get_websocket_request( } pub async fn list_websocket_requests( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(WebsocketRequestIden::Table) @@ -1304,10 +1307,10 @@ pub async fn list_websocket_requests( } pub async fn list_websocket_events( - mgr: &impl Manager, + app_handle: &AppHandle, connection_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(WebsocketEventIden::Table) @@ -1320,7 +1323,7 @@ pub async fn list_websocket_events( } pub async fn upsert_cookie_jar( - window: &WebviewWindow, + app_handle: &AppHandle, cookie_jar: &CookieJar, update_source: &UpdateSource, ) -> Result { @@ -1330,7 +1333,7 @@ pub async fn upsert_cookie_jar( }; let trimmed_name = cookie_jar.name.trim(); - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() @@ -1365,22 +1368,22 @@ pub async fn upsert_cookie_jar( let mut stmt = db.prepare(sql.as_str())?; let m: CookieJar = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::CookieJar(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::CookieJar(m.to_owned()), update_source); Ok(m) } pub async fn ensure_base_environment( - window: &WebviewWindow, + app_handle: &AppHandle, workspace_id: &str, ) -> Result<()> { - let environments = list_environments(window, workspace_id).await?; + let environments = list_environments(app_handle, workspace_id).await?; let base_environment = environments.iter().find(|e| e.environment_id == None && e.workspace_id == workspace_id); if let None = base_environment { info!("Creating base environment for {workspace_id}"); upsert_environment( - window, + app_handle, Environment { workspace_id: workspace_id.to_string(), name: "Global Variables".to_string(), @@ -1395,11 +1398,11 @@ pub async fn ensure_base_environment( } pub async fn list_environments( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result> { let environments: Vec = { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(EnvironmentIden::Table) @@ -1416,13 +1419,13 @@ pub async fn list_environments( } pub async fn delete_environment( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let env = get_environment(window, id).await?; + let env = get_environment(app_handle, id).await?; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() @@ -1432,14 +1435,14 @@ pub async fn delete_environment( db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(window, &AnyModel::Environment(env.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::Environment(env.to_owned()), update_source); Ok(env) } const SETTINGS_ID: &str = "default"; -async fn get_settings(mgr: &impl Manager) -> Result> { - let dbm = &*mgr.state::(); +async fn get_settings(app_handle: &AppHandle) -> Result> { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -1451,14 +1454,14 @@ async fn get_settings(mgr: &impl Manager) -> Result(mgr: &impl Manager) -> Settings { - match get_settings(mgr).await { +pub async fn get_or_create_settings(app_handle: &AppHandle) -> Settings { + match get_settings(app_handle).await { Ok(Some(settings)) => return settings, Err(e) => panic!("Failed to get settings {e:?}"), Ok(None) => {} }; - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() @@ -1473,7 +1476,7 @@ pub async fn get_or_create_settings(mgr: &impl Manager) -> Settin } pub async fn update_settings( - window: &WebviewWindow, + app_handle: &AppHandle, settings: Settings, update_source: &UpdateSource, ) -> Result { @@ -1484,7 +1487,7 @@ pub async fn update_settings( settings.created_at }; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::update() @@ -1518,12 +1521,12 @@ pub async fn update_settings( let mut stmt = db.prepare(sql.as_str())?; let m: Settings = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::Settings(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::Settings(m.to_owned()), update_source); Ok(m) } pub async fn upsert_environment( - window: &WebviewWindow, + app_handle: &AppHandle, environment: Environment, update_source: &UpdateSource, ) -> Result { @@ -1533,7 +1536,7 @@ pub async fn upsert_environment( }; let trimmed_name = environment.name.trim(); - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() @@ -1570,12 +1573,15 @@ pub async fn upsert_environment( let mut stmt = db.prepare(sql.as_str())?; let m: Environment = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::Environment(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::Environment(m.to_owned()), update_source); Ok(m) } -pub async fn get_environment(mgr: &impl Manager, id: &str) -> Result { - let dbm = &*mgr.state::(); +pub async fn get_environment( + app_handle: &AppHandle, + id: &str, +) -> Result { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -1588,10 +1594,10 @@ pub async fn get_environment(mgr: &impl Manager, id: &str) -> Res } pub async fn get_base_environment( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -1607,8 +1613,8 @@ pub async fn get_base_environment( Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) } -pub async fn get_plugin(mgr: &impl Manager, id: &str) -> Result { - let dbm = &*mgr.state::(); +pub async fn get_plugin(app_handle: &AppHandle, id: &str) -> Result { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -1620,8 +1626,8 @@ pub async fn get_plugin(mgr: &impl Manager, id: &str) -> Result

(mgr: &impl Manager) -> Result> { - let dbm = &*mgr.state::(); +pub async fn list_plugins(app_handle: &AppHandle) -> Result> { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -1635,7 +1641,7 @@ pub async fn list_plugins(mgr: &impl Manager) -> Result( - window: &WebviewWindow, + app_handle: &AppHandle, plugin: Plugin, update_source: &UpdateSource, ) -> Result { @@ -1643,7 +1649,7 @@ pub async fn upsert_plugin( "" => generate_model_id(ModelType::TypePlugin), _ => plugin.id.to_string(), }; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() @@ -1682,19 +1688,19 @@ pub async fn upsert_plugin( let mut stmt = db.prepare(sql.as_str())?; let m: Plugin = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::Plugin(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::Plugin(m.to_owned()), update_source); Ok(m) } pub async fn delete_plugin( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let plugin = get_plugin(window, id).await?; + let plugin = get_plugin(app_handle, id).await?; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() @@ -1703,12 +1709,12 @@ pub async fn delete_plugin( .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(window, &AnyModel::Plugin(plugin.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::Plugin(plugin.to_owned()), update_source); Ok(plugin) } -pub async fn get_folder(mgr: &impl Manager, id: &str) -> Result { - let dbm = &*mgr.state::(); +pub async fn get_folder(app_handle: &AppHandle, id: &str) -> Result { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -1721,10 +1727,10 @@ pub async fn get_folder(mgr: &impl Manager, id: &str) -> Result( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -1739,14 +1745,14 @@ pub async fn list_folders( } pub async fn delete_folder( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let folder = get_folder(window, id).await?; + let folder = get_folder(app_handle, id).await?; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() @@ -1755,12 +1761,12 @@ pub async fn delete_folder( .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(window, &AnyModel::Folder(folder.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::Folder(folder.to_owned()), update_source); Ok(folder) } pub async fn upsert_folder( - window: &WebviewWindow, + app_handle: &AppHandle, folder: Folder, update_source: &UpdateSource, @@ -1771,7 +1777,7 @@ pub async fn upsert_folder( }; let trimmed_name = folder.name.trim(); - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() @@ -1812,90 +1818,92 @@ pub async fn upsert_folder( let mut stmt = db.prepare(sql.as_str())?; let m: Folder = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::Folder(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::Folder(m.to_owned()), update_source); Ok(m) } pub async fn duplicate_http_request( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let mut request = match get_http_request(window, id).await? { + let mut request = match get_http_request(app_handle, id).await? { None => return Err(ModelNotFound(id.to_string())), Some(r) => r, }; request.id = "".to_string(); request.sort_priority = request.sort_priority + 0.001; - upsert_http_request(window, request, update_source).await + upsert_http_request(app_handle, request, update_source).await } pub async fn duplicate_folder( - window: &WebviewWindow, + app_handle: &AppHandle, src_folder: &Folder, + update_source: &UpdateSource, ) -> Result<()> { let workspace_id = src_folder.workspace_id.as_str(); - let http_requests = list_http_requests(window, workspace_id) + let http_requests = list_http_requests(app_handle, workspace_id) .await? .into_iter() .filter(|m| m.folder_id.as_ref() == Some(&src_folder.id)); - let grpc_requests = list_grpc_requests(window, workspace_id) + let grpc_requests = list_grpc_requests(app_handle, workspace_id) .await? .into_iter() .filter(|m| m.folder_id.as_ref() == Some(&src_folder.id)); - let folders = list_folders(window, workspace_id) + let folders = list_folders(app_handle, workspace_id) .await? .into_iter() .filter(|m| m.folder_id.as_ref() == Some(&src_folder.id)); let new_folder = upsert_folder( - window, + app_handle, Folder { id: "".into(), sort_priority: src_folder.sort_priority + 0.001, ..src_folder.clone() }, - &UpdateSource::Window, + update_source, ) .await?; for m in http_requests { upsert_http_request( - window, + app_handle, HttpRequest { id: "".into(), folder_id: Some(new_folder.id.clone()), sort_priority: m.sort_priority + 0.001, ..m }, - &UpdateSource::Window, + update_source, ) .await?; } for m in grpc_requests { upsert_grpc_request( - window, + app_handle, GrpcRequest { id: "".into(), folder_id: Some(new_folder.id.clone()), sort_priority: m.sort_priority + 0.001, ..m }, - &UpdateSource::Window, + update_source, ) .await?; } for m in folders { // Recurse down Box::pin(duplicate_folder( - window, + app_handle, &Folder { folder_id: Some(new_folder.id.clone()), ..m }, + update_source, )) .await?; } @@ -1903,7 +1911,7 @@ pub async fn duplicate_folder( } pub async fn upsert_http_request( - window: &WebviewWindow, + app_handle: &AppHandle, request: HttpRequest, update_source: &UpdateSource, ) -> Result { @@ -1913,7 +1921,7 @@ pub async fn upsert_http_request( }; let trimmed_name = request.name.trim(); - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() @@ -1979,15 +1987,15 @@ pub async fn upsert_http_request( let mut stmt = db.prepare(sql.as_str())?; let m: HttpRequest = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::HttpRequest(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::HttpRequest(m.to_owned()), update_source); Ok(m) } pub async fn list_http_requests( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(HttpRequestIden::Table) @@ -2001,10 +2009,10 @@ pub async fn list_http_requests( } pub async fn get_http_request( - mgr: &impl Manager, + app_handle: &AppHandle, id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() @@ -2017,19 +2025,19 @@ pub async fn get_http_request( } pub async fn delete_http_request( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let req = match get_http_request(window, id).await? { + let req = match get_http_request(app_handle, id).await? { None => return Err(ModelNotFound(id.to_string())), Some(r) => r, }; // DB deletes will cascade but this will delete the files - delete_all_http_responses_for_request(window, id, update_source).await?; + delete_all_http_responses_for_request(app_handle, id, update_source).await?; - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() .from_table(HttpRequestIden::Table) @@ -2037,17 +2045,17 @@ pub async fn delete_http_request( .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(window, &AnyModel::HttpRequest(req.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::HttpRequest(req.to_owned()), update_source); Ok(req) } pub async fn create_default_http_response( - window: &WebviewWindow, + app_handle: &AppHandle, request_id: &str, update_source: &UpdateSource, ) -> Result { create_http_response( - &window, + &app_handle, request_id, 0, 0, @@ -2067,7 +2075,7 @@ pub async fn create_default_http_response( #[allow(clippy::too_many_arguments)] pub async fn create_http_response( - window: &WebviewWindow, + app_handle: &AppHandle, request_id: &str, elapsed: i64, elapsed_headers: i64, @@ -2082,18 +2090,18 @@ pub async fn create_http_response( remote_addr: Option<&str>, update_source: &UpdateSource, ) -> Result { - let responses = list_http_responses_for_request(window, request_id, None).await?; + let responses = list_http_responses_for_request(app_handle, request_id, None).await?; for response in responses.iter().skip(MAX_HISTORY_ITEMS - 1) { debug!("Deleting old response {}", response.id); - delete_http_response(window, response.id.as_str(), update_source).await?; + delete_http_response(app_handle, response.id.as_str(), update_source).await?; } - let req = match get_http_request(window, request_id).await? { + let req = match get_http_request(app_handle, request_id).await? { None => return Err(ModelNotFound(request_id.to_string())), Some(r) => r, }; let id = generate_model_id(ModelType::TypeHttpResponse); - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() @@ -2139,12 +2147,14 @@ pub async fn create_http_response( let mut stmt = db.prepare(sql.as_str())?; let m: HttpResponse = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::HttpResponse(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::HttpResponse(m.to_owned()), update_source); Ok(m) } -pub async fn cancel_pending_websocket_connections(mgr: &impl Manager) -> Result<()> { - let dbm = &*mgr.state::(); +pub async fn cancel_pending_websocket_connections( + app_handle: &AppHandle, +) -> Result<()> { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let closed = serde_json::to_value(&WebsocketConnectionState::Closed)?; @@ -2192,23 +2202,23 @@ pub async fn cancel_pending_http_responses(app: &AppHandle) -> Result<()> { } pub async fn update_response_if_id( - window: &WebviewWindow, + app_handle: &AppHandle, response: &HttpResponse, update_source: &UpdateSource, ) -> Result { if response.id.is_empty() { Ok(response.clone()) } else { - update_http_response(window, response, update_source).await + update_http_response(app_handle, response, update_source).await } } pub async fn update_http_response( - window: &WebviewWindow, + app_handle: &AppHandle, response: &HttpResponse, update_source: &UpdateSource, ) -> Result { - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::update() @@ -2242,15 +2252,15 @@ pub async fn update_http_response( let mut stmt = db.prepare(sql.as_str())?; let m: HttpResponse = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(window, &AnyModel::HttpResponse(m.to_owned()), update_source); + emit_upserted_model(app_handle, &AnyModel::HttpResponse(m.to_owned()), update_source); Ok(m) } pub async fn get_http_response( - mgr: &impl Manager, + app_handle: &AppHandle, id: &str, ) -> Result { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(HttpResponseIden::Table) @@ -2262,11 +2272,11 @@ pub async fn get_http_response( } pub async fn delete_http_response( - window: &WebviewWindow, + app_handle: &AppHandle, id: &str, update_source: &UpdateSource, ) -> Result { - let resp = get_http_response(window, id).await?; + let resp = get_http_response(app_handle, id).await?; // Delete the body file if it exists if let Some(p) = resp.body_path.clone() { @@ -2275,7 +2285,7 @@ pub async fn delete_http_response( }; } - let dbm = &*window.app_handle().state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() .from_table(HttpResponseIden::Table) @@ -2283,39 +2293,39 @@ pub async fn delete_http_response( .build_rusqlite(SqliteQueryBuilder); db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(window, &AnyModel::HttpResponse(resp.to_owned()), update_source); + emit_deleted_model(app_handle, &AnyModel::HttpResponse(resp.to_owned()), update_source); Ok(resp) } pub async fn delete_all_http_responses_for_request( - window: &WebviewWindow, + app_handle: &AppHandle, request_id: &str, update_source: &UpdateSource, ) -> Result<()> { - for r in list_http_responses_for_request(window, request_id, None).await? { - delete_http_response(window, &r.id, update_source).await?; + for r in list_http_responses_for_request(app_handle, request_id, None).await? { + delete_http_response(app_handle, &r.id, update_source).await?; } Ok(()) } pub async fn delete_all_http_responses_for_workspace( - window: &WebviewWindow, + app_handle: &AppHandle, workspace_id: &str, update_source: &UpdateSource, ) -> Result<()> { - for r in list_http_responses_for_workspace(window, workspace_id, None).await? { - delete_http_response(window, &r.id, update_source).await?; + for r in list_http_responses_for_workspace(app_handle, workspace_id, None).await? { + delete_http_response(app_handle, &r.id, update_source).await?; } Ok(()) } pub async fn list_http_responses_for_workspace( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, limit: Option, ) -> Result> { let limit_unwrapped = limit.unwrap_or_else(|| i64::MAX); - let dbm = mgr.state::(); + let dbm = app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(HttpResponseIden::Table) @@ -2330,12 +2340,12 @@ pub async fn list_http_responses_for_workspace( } pub async fn list_http_responses_for_request( - mgr: &impl Manager, + app_handle: &AppHandle, request_id: &str, limit: Option, ) -> Result> { let limit_unwrapped = limit.unwrap_or_else(|| i64::MAX); - let dbm = mgr.state::(); + let dbm = app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(HttpResponseIden::Table) @@ -2350,10 +2360,10 @@ pub async fn list_http_responses_for_request( } pub async fn list_responses_by_workspace_id( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(HttpResponseIden::Table) @@ -2367,11 +2377,11 @@ pub async fn list_responses_by_workspace_id( } pub async fn get_sync_state_for_model( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, model_id: &str, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(SyncStateIden::Table) @@ -2387,11 +2397,11 @@ pub async fn get_sync_state_for_model( } pub async fn list_sync_states_for_workspace( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, sync_dir: &Path, ) -> Result> { - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::select() .from(SyncStateIden::Table) @@ -2408,7 +2418,7 @@ pub async fn list_sync_states_for_workspace( } pub async fn upsert_sync_state( - mgr: &impl Manager, + app_handle: &AppHandle, sync_state: SyncState, ) -> Result { let id = match sync_state.id.as_str() { @@ -2416,7 +2426,7 @@ pub async fn upsert_sync_state( _ => sync_state.id.to_string(), }; - let dbm = &*mgr.state::(); + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::insert() @@ -2462,8 +2472,8 @@ pub async fn upsert_sync_state( Ok(m) } -pub async fn delete_sync_state(mgr: &impl Manager, id: &str) -> Result<()> { - let dbm = &*mgr.app_handle().state::(); +pub async fn delete_sync_state(app_handle: &AppHandle, id: &str) -> Result<()> { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await.get().unwrap(); let (sql, params) = Query::delete() @@ -2474,8 +2484,8 @@ pub async fn delete_sync_state(mgr: &impl Manager, id: &str) -> R Ok(()) } -pub async fn debug_pool(mgr: &impl Manager) { - let dbm = &*mgr.state::(); +pub async fn debug_pool(app_handle: &AppHandle) { + let dbm = &*app_handle.state::(); let db = dbm.0.lock().await; debug!("Debug database state: {:?}", db.state()); } @@ -2501,46 +2511,51 @@ pub fn generate_id() -> String { #[ts(export, export_to = "gen_models.ts")] pub struct ModelPayload { pub model: AnyModel, - pub window_label: String, pub update_source: UpdateSource, } #[derive(Debug, Clone, Serialize, Deserialize, TS)] -#[serde(rename_all = "snake_case")] +#[serde(rename_all = "snake_case", tag = "type")] #[ts(export, export_to = "gen_models.ts")] pub enum UpdateSource { Sync, - Window, + Window { label: String }, Plugin, Background, Import, } +impl UpdateSource { + pub fn from_window(window: &WebviewWindow) -> Self { + Self::Window { + label: window.label().to_string(), + } + } +} + fn emit_upserted_model( - window: &WebviewWindow, + app_handle: &AppHandle, model: &AnyModel, update_source: &UpdateSource, ) { let payload = ModelPayload { model: model.to_owned(), - window_label: window.label().to_string(), update_source: update_source.to_owned(), }; - window.emit("upserted_model", payload).unwrap(); + app_handle.emit("upserted_model", payload).unwrap(); } fn emit_deleted_model( - window: &WebviewWindow, + app_handle: &AppHandle, model: &AnyModel, update_source: &UpdateSource, ) { let payload = ModelPayload { model: model.to_owned(), - window_label: window.label().to_string(), update_source: update_source.to_owned(), }; - window.emit("deleted_model", payload).unwrap(); + app_handle.emit("deleted_model", payload).unwrap(); } pub fn listen_to_model_delete(app_handle: &AppHandle, handler: F) @@ -2596,7 +2611,7 @@ pub struct BatchUpsertResult { } pub async fn batch_upsert( - window: &WebviewWindow, + app_handle: &AppHandle, workspaces: Vec, environments: Vec, folders: Vec, @@ -2610,7 +2625,7 @@ pub async fn batch_upsert( if workspaces.len() > 0 { info!("Batch inserting {} workspaces", workspaces.len()); for v in workspaces { - let x = upsert_workspace(&window, v, update_source).await?; + let x = upsert_workspace(&app_handle, v, update_source).await?; imported_resources.workspaces.push(x.clone()); } } @@ -2630,7 +2645,7 @@ pub async fn batch_upsert( if let Some(_) = imported_resources.environments.iter().find(|f| f.id == v.id) { continue; } - let x = upsert_environment(&window, v, update_source).await?; + let x = upsert_environment(&app_handle, v, update_source).await?; imported_resources.environments.push(x.clone()); } } @@ -2651,7 +2666,7 @@ pub async fn batch_upsert( if let Some(_) = imported_resources.folders.iter().find(|f| f.id == v.id) { continue; } - let x = upsert_folder(&window, v, update_source).await?; + let x = upsert_folder(&app_handle, v, update_source).await?; imported_resources.folders.push(x.clone()); } } @@ -2660,7 +2675,7 @@ pub async fn batch_upsert( if http_requests.len() > 0 { for v in http_requests { - let x = upsert_http_request(&window, v, update_source).await?; + let x = upsert_http_request(&app_handle, v, update_source).await?; imported_resources.http_requests.push(x.clone()); } info!("Imported {} http_requests", imported_resources.http_requests.len()); @@ -2668,7 +2683,7 @@ pub async fn batch_upsert( if grpc_requests.len() > 0 { for v in grpc_requests { - let x = upsert_grpc_request(&window, v, update_source).await?; + let x = upsert_grpc_request(&app_handle, v, update_source).await?; imported_resources.grpc_requests.push(x.clone()); } info!("Imported {} grpc_requests", imported_resources.grpc_requests.len()); @@ -2676,7 +2691,7 @@ pub async fn batch_upsert( if websocket_requests.len() > 0 { for v in websocket_requests { - let x = upsert_websocket_request(&window, v, update_source).await?; + let x = upsert_websocket_request(&app_handle, v, update_source).await?; imported_resources.websocket_requests.push(x.clone()); } info!("Imported {} websocket_requests", imported_resources.websocket_requests.len()); @@ -2686,12 +2701,12 @@ pub async fn batch_upsert( } pub async fn get_workspace_export_resources( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_ids: Vec<&str>, include_environments: bool, ) -> Result { let mut data = WorkspaceExport { - yaak_version: mgr.package_info().version.clone().to_string(), + yaak_version: app_handle.package_info().version.clone().to_string(), yaak_schema: 3, timestamp: Utc::now().naive_utc(), resources: BatchUpsertResult { @@ -2705,14 +2720,18 @@ pub async fn get_workspace_export_resources( }; for workspace_id in workspace_ids { - data.resources.workspaces.push(get_workspace(mgr, workspace_id).await?); - data.resources.environments.append(&mut list_environments(mgr, workspace_id).await?); - data.resources.folders.append(&mut list_folders(mgr, workspace_id).await?); - data.resources.http_requests.append(&mut list_http_requests(mgr, workspace_id).await?); - data.resources.grpc_requests.append(&mut list_grpc_requests(mgr, workspace_id).await?); + data.resources.workspaces.push(get_workspace(app_handle, workspace_id).await?); + data.resources.environments.append(&mut list_environments(app_handle, workspace_id).await?); + data.resources.folders.append(&mut list_folders(app_handle, workspace_id).await?); + data.resources + .http_requests + .append(&mut list_http_requests(app_handle, workspace_id).await?); + data.resources + .grpc_requests + .append(&mut list_grpc_requests(app_handle, workspace_id).await?); data.resources .websocket_requests - .append(&mut list_websocket_requests(mgr, workspace_id).await?); + .append(&mut list_websocket_requests(app_handle, workspace_id).await?); } // Nuke environments if we don't want them diff --git a/src-tauri/yaak-sync/src/commands.rs b/src-tauri/yaak-sync/src/commands.rs index 6f1b5474b..b5cbe1adb 100644 --- a/src-tauri/yaak-sync/src/commands.rs +++ b/src-tauri/yaak-sync/src/commands.rs @@ -9,17 +9,17 @@ use log::warn; use serde::{Deserialize, Serialize}; use std::path::Path; use tauri::ipc::Channel; -use tauri::{command, Listener, Runtime, WebviewWindow}; +use tauri::{command, AppHandle, Listener, Runtime}; use tokio::sync::watch; use ts_rs::TS; #[command] pub async fn calculate( - window: WebviewWindow, + app_handle: AppHandle, workspace_id: &str, sync_dir: &Path, ) -> Result> { - let db_candidates = get_db_candidates(&window, workspace_id, sync_dir).await?; + let db_candidates = get_db_candidates(&app_handle, workspace_id, sync_dir).await?; let fs_candidates = get_fs_candidates(sync_dir) .await? .into_iter() @@ -40,13 +40,13 @@ pub async fn calculate_fs(dir: &Path) -> Result> { #[command] pub async fn apply( - window: WebviewWindow, + app_handle: AppHandle, sync_ops: Vec, sync_dir: &Path, workspace_id: &str, ) -> Result<()> { - let sync_state_ops = apply_sync_ops(&window, &workspace_id, sync_dir, sync_ops).await?; - apply_sync_state_ops(&window, workspace_id, sync_dir, sync_state_ops).await + let sync_state_ops = apply_sync_ops(&app_handle, &workspace_id, sync_dir, sync_ops).await?; + apply_sync_state_ops(&app_handle, workspace_id, sync_dir, sync_state_ops).await } #[derive(Debug, Clone, Serialize, Deserialize, TS)] @@ -58,7 +58,7 @@ pub(crate) struct WatchResult { #[command] pub async fn watch( - window: WebviewWindow, + app_handle: AppHandle, sync_dir: &Path, workspace_id: &str, channel: Channel, @@ -67,16 +67,16 @@ pub async fn watch( watch_directory(&sync_dir, channel, cancel_rx).await?; - let window_inner = window.clone(); + let app_handle_inner = app_handle.clone(); let unlisten_event = format!("watch-unlisten-{}-{}", workspace_id, Utc::now().timestamp_millis()); - // TODO: Figure out a way to unlisten when the client window refreshes or closes. Perhaps with + // TODO: Figure out a way to unlisten when the client app_handle refreshes or closes. Perhaps with // a heartbeat mechanism, or ensuring only a single subscription per workspace (at least // this won't create `n` subs). We could also maybe have a global fs watcher that we keep // adding to here. - window.listen_any(unlisten_event.clone(), move |event| { - window_inner.unlisten(event.id()); + app_handle.listen_any(unlisten_event.clone(), move |event| { + app_handle_inner.unlisten(event.id()); if let Err(e) = cancel_tx.send(()) { warn!("Failed to send cancel signal to watcher {e:?}"); } diff --git a/src-tauri/yaak-sync/src/sync.rs b/src-tauri/yaak-sync/src/sync.rs index 9d8728ffe..b7482c8dd 100644 --- a/src-tauri/yaak-sync/src/sync.rs +++ b/src-tauri/yaak-sync/src/sync.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fmt::{Display, Formatter}; use std::path::{Path, PathBuf}; -use tauri::{Manager, Runtime, WebviewWindow}; +use tauri::{AppHandle, Runtime}; use tokio::fs; use tokio::fs::File; use tokio::io::AsyncWriteExt; @@ -106,17 +106,21 @@ pub(crate) struct FsCandidate { } pub(crate) async fn get_db_candidates( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, sync_dir: &Path, ) -> Result> { - let models: HashMap<_, _> = - workspace_models(mgr, workspace_id).await?.into_iter().map(|m| (m.id(), m)).collect(); - let sync_states: HashMap<_, _> = list_sync_states_for_workspace(mgr, workspace_id, sync_dir) + let models: HashMap<_, _> = workspace_models(app_handle, workspace_id) .await? .into_iter() - .map(|s| (s.model_id.clone(), s)) + .map(|m| (m.id(), m)) .collect(); + let sync_states: HashMap<_, _> = + list_sync_states_for_workspace(app_handle, workspace_id, sync_dir) + .await? + .into_iter() + .map(|s| (s.model_id.clone(), s)) + .collect(); // 1. Add candidates for models (created/modified/unmodified) let mut candidates: Vec = models @@ -223,7 +227,7 @@ pub(crate) fn compute_sync_ops( model: model.to_owned(), state: sync_state.to_owned(), } - }, + } (Some(DbCandidate::Modified(model, sync_state)), None) => SyncOp::FsUpdate { model: model.to_owned(), state: sync_state.to_owned(), @@ -285,10 +289,11 @@ pub(crate) fn compute_sync_ops( } async fn workspace_models( - mgr: &impl Manager, + app_handle: &AppHandle, workspace_id: &str, ) -> Result> { - let resources = get_workspace_export_resources(mgr, vec![workspace_id], true).await?.resources; + let resources = + get_workspace_export_resources(app_handle, vec![workspace_id], true).await?.resources; let workspace = resources.workspaces.iter().find(|w| w.id == workspace_id); let workspace = match workspace { @@ -318,7 +323,7 @@ async fn workspace_models( } pub(crate) async fn apply_sync_ops( - window: &WebviewWindow, + app_handle: &AppHandle, workspace_id: &str, sync_dir: &Path, sync_ops: Vec, @@ -429,7 +434,7 @@ pub(crate) async fn apply_sync_ops( } } SyncOp::DbDelete { model, state } => { - delete_model(window, &model).await?; + delete_model(app_handle, &model).await?; SyncStateOp::Delete { state: state.to_owned(), } @@ -438,7 +443,7 @@ pub(crate) async fn apply_sync_ops( } let upserted_models = batch_upsert( - window, + app_handle, workspaces_to_upsert, environments_to_upsert, folders_to_upsert, @@ -452,7 +457,7 @@ pub(crate) async fn apply_sync_ops( // Ensure we creat WorkspaceMeta models for each new workspace, with the appropriate sync dir let sync_dir_string = sync_dir.to_string_lossy().to_string(); for workspace in upserted_models.workspaces { - let r = match get_workspace_meta(window, &workspace).await { + let r = match get_workspace_meta(app_handle, &workspace).await { Ok(Some(m)) => { if m.setting_sync_dir == Some(sync_dir_string.clone()) { // We don't need to update if unchanged @@ -462,7 +467,7 @@ pub(crate) async fn apply_sync_ops( setting_sync_dir: Some(sync_dir.to_string_lossy().to_string()), ..m }; - upsert_workspace_meta(window, wm, &UpdateSource::Sync).await + upsert_workspace_meta(app_handle, wm, &UpdateSource::Sync).await } Ok(None) => { let wm = WorkspaceMeta { @@ -470,7 +475,7 @@ pub(crate) async fn apply_sync_ops( setting_sync_dir: Some(sync_dir.to_string_lossy().to_string()), ..Default::default() }; - upsert_workspace_meta(window, wm, &UpdateSource::Sync).await + upsert_workspace_meta(app_handle, wm, &UpdateSource::Sync).await } Err(e) => Err(e), }; @@ -501,7 +506,7 @@ pub(crate) enum SyncStateOp { } pub(crate) async fn apply_sync_state_ops( - window: &WebviewWindow, + app_handle: &AppHandle, workspace_id: &str, sync_dir: &Path, ops: Vec, @@ -522,7 +527,7 @@ pub(crate) async fn apply_sync_state_ops( flushed_at: Utc::now().naive_utc(), ..Default::default() }; - upsert_sync_state(window, sync_state).await?; + upsert_sync_state(app_handle, sync_state).await?; } SyncStateOp::Update { state: sync_state, @@ -536,10 +541,10 @@ pub(crate) async fn apply_sync_state_ops( flushed_at: Utc::now().naive_utc(), ..sync_state }; - upsert_sync_state(window, sync_state).await?; + upsert_sync_state(app_handle, sync_state).await?; } SyncStateOp::Delete { state } => { - delete_sync_state(window, state.id.as_str()).await?; + delete_sync_state(app_handle, state.id.as_str()).await?; } } } @@ -551,25 +556,25 @@ fn derive_model_filename(m: &SyncModel) -> PathBuf { Path::new(&rel).to_path_buf() } -async fn delete_model(window: &WebviewWindow, model: &SyncModel) -> Result<()> { +async fn delete_model(app_handle: &AppHandle, model: &SyncModel) -> Result<()> { match model { SyncModel::Workspace(m) => { - delete_workspace(window, m.id.as_str(), &UpdateSource::Sync).await?; + delete_workspace(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; } SyncModel::Environment(m) => { - delete_environment(window, m.id.as_str(), &UpdateSource::Sync).await?; + delete_environment(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; } SyncModel::Folder(m) => { - delete_folder(window, m.id.as_str(), &UpdateSource::Sync).await?; + delete_folder(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; } SyncModel::HttpRequest(m) => { - delete_http_request(window, m.id.as_str(), &UpdateSource::Sync).await?; + delete_http_request(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; } SyncModel::GrpcRequest(m) => { - delete_grpc_request(window, m.id.as_str(), &UpdateSource::Sync).await?; + delete_grpc_request(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; } SyncModel::WebsocketRequest(m) => { - delete_websocket_request(window, m.id.as_str(), &UpdateSource::Sync).await?; + delete_websocket_request(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; } }; Ok(()) diff --git a/src-tauri/yaak-templates/src/renderer.rs b/src-tauri/yaak-templates/src/renderer.rs index 989c61a60..a31c10e6e 100644 --- a/src-tauri/yaak-templates/src/renderer.rs +++ b/src-tauri/yaak-templates/src/renderer.rs @@ -1,7 +1,6 @@ use crate::error::Error::{RenderStackExceededError, VariableNotFound}; use crate::error::Result; use crate::{Parser, Token, Tokens, Val}; -use log::warn; use serde_json::json; use std::collections::HashMap; use std::future::Future; @@ -113,13 +112,7 @@ async fn render_value( let v = Box::pin(render_value(a.value, vars, cb, depth)).await?; resolved_args.insert(a.name, v); } - match cb.run(name.as_str(), resolved_args.clone()).await { - Ok(s) => s, - Err(e) => { - warn!("Failed to run template callback {}({:?}): {}", name, resolved_args, e); - "".to_string() - } - } + cb.run(name.as_str(), resolved_args.clone()).await? } Val::Null => "".into(), }; @@ -324,7 +317,7 @@ mod parse_and_render_tests { #[tokio::test] async fn render_fn_err() -> Result<()> { let vars = HashMap::new(); - let template = r#"${[ error() ]}"#; + let template = r#"hello ${[ error() ]}"#; struct CB {} impl TemplateCallback for CB { diff --git a/src-tauri/yaak-ws/src/commands.rs b/src-tauri/yaak-ws/src/commands.rs index c62a3c3b6..b8e533fee 100644 --- a/src-tauri/yaak-ws/src/commands.rs +++ b/src-tauri/yaak-ws/src/commands.rs @@ -5,7 +5,7 @@ use crate::render::render_request; use log::{info, warn}; use std::str::FromStr; use tauri::http::{HeaderMap, HeaderName}; -use tauri::{AppHandle, Manager, Runtime, State, Url, WebviewWindow}; +use tauri::{AppHandle, Runtime, State, Url, WebviewWindow}; use tokio::sync::{mpsc, Mutex}; use tokio_tungstenite::tungstenite::http::HeaderValue; use tokio_tungstenite::tungstenite::Message; @@ -28,41 +28,54 @@ use yaak_plugins::template_callback::PluginTemplateCallback; #[tauri::command] pub(crate) async fn upsert_request( request: WebsocketRequest, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - Ok(queries::upsert_websocket_request(&w, request, &UpdateSource::Window).await?) + Ok(queries::upsert_websocket_request(&app_handle, request, &UpdateSource::from_window(&window)) + .await?) } #[tauri::command] pub(crate) async fn duplicate_request( request_id: &str, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - Ok(queries::duplicate_websocket_request(&w, request_id, &UpdateSource::Window).await?) + Ok(queries::duplicate_websocket_request( + &app_handle, + request_id, + &UpdateSource::from_window(&window), + ) + .await?) } #[tauri::command] pub(crate) async fn delete_request( request_id: &str, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - Ok(queries::delete_websocket_request(&w, request_id, &UpdateSource::Window).await?) + Ok(queries::delete_websocket_request(&app_handle, request_id, &UpdateSource::from_window(&window)).await?) } #[tauri::command] pub(crate) async fn delete_connection( connection_id: &str, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result { - Ok(queries::delete_websocket_connection(&w, connection_id, &UpdateSource::Window).await?) + Ok(queries::delete_websocket_connection(&app_handle, connection_id, &UpdateSource::from_window(&window)) + .await?) } #[tauri::command] pub(crate) async fn delete_connections( request_id: &str, - w: WebviewWindow, + app_handle: AppHandle, + window: WebviewWindow, ) -> Result<()> { - Ok(queries::delete_all_websocket_connections(&w, request_id, &UpdateSource::Window).await?) + Ok(queries::delete_all_websocket_connections(&app_handle, request_id, &UpdateSource::from_window(&window)) + .await?) } #[tauri::command] @@ -93,24 +106,26 @@ pub(crate) async fn list_connections( pub(crate) async fn send( connection_id: &str, environment_id: Option<&str>, + app_handle: AppHandle, window: WebviewWindow, ws_manager: State<'_, Mutex>, ) -> Result { - let connection = get_websocket_connection(&window, connection_id).await?; - let unrendered_request = get_websocket_request(&window, &connection.request_id) + let connection = get_websocket_connection(&app_handle, connection_id).await?; + let unrendered_request = get_websocket_request(&app_handle, &connection.request_id) .await? .ok_or(GenericError("WebSocket Request not found".to_string()))?; let environment = match environment_id { - Some(id) => Some(get_environment(&window, id).await?), + Some(id) => Some(get_environment(&app_handle, id).await?), None => None, }; - let base_environment = get_base_environment(&window, &unrendered_request.workspace_id).await?; + let base_environment = + get_base_environment(&app_handle, &unrendered_request.workspace_id).await?; let request = render_request( &unrendered_request, &base_environment, environment.as_ref(), &PluginTemplateCallback::new( - window.app_handle(), + &app_handle, &WindowContext::from_window(&window), RenderPurpose::Send, ), @@ -121,7 +136,7 @@ pub(crate) async fn send( ws_manager.send(&connection.id, Message::Text(request.message.clone().into())).await?; upsert_websocket_event( - &window, + &app_handle, WebsocketEvent { connection_id: connection.id.clone(), request_id: request.id.clone(), @@ -131,7 +146,7 @@ pub(crate) async fn send( message: request.message.into(), ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -142,17 +157,18 @@ pub(crate) async fn send( #[tauri::command] pub(crate) async fn close( connection_id: &str, + app_handle: AppHandle, window: WebviewWindow, ws_manager: State<'_, Mutex>, ) -> Result { - let connection = get_websocket_connection(&window, connection_id).await?; + let connection = get_websocket_connection(&app_handle, connection_id).await?; let connection = upsert_websocket_connection( - &window, + &app_handle, &WebsocketConnection { state: WebsocketConnectionState::Closing, ..connection }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -170,24 +186,26 @@ pub(crate) async fn connect( request_id: &str, environment_id: Option<&str>, cookie_jar_id: Option<&str>, + app_handle: AppHandle, window: WebviewWindow, plugin_manager: State<'_, PluginManager>, ws_manager: State<'_, Mutex>, ) -> Result { - let unrendered_request = get_websocket_request(&window, request_id) + let unrendered_request = get_websocket_request(&app_handle, request_id) .await? .ok_or(GenericError("Failed to find GRPC request".to_string()))?; let environment = match environment_id { - Some(id) => Some(get_environment(&window, id).await?), + Some(id) => Some(get_environment(&app_handle, id).await?), None => None, }; - let base_environment = get_base_environment(&window, &unrendered_request.workspace_id).await?; + let base_environment = + get_base_environment(&app_handle, &unrendered_request.workspace_id).await?; let request = render_request( &unrendered_request, &base_environment, environment.as_ref(), &PluginTemplateCallback::new( - window.app_handle(), + &app_handle, &WindowContext::from_window(&window), RenderPurpose::Send, ), @@ -224,18 +242,18 @@ pub(crate) async fn connect( // TODO: Handle cookies let _cookie_jar = match cookie_jar_id { - Some(id) => Some(get_cookie_jar(&window, id).await?), + Some(id) => Some(get_cookie_jar(&app_handle, id).await?), None => None, }; let connection = upsert_websocket_connection( - &window, + &app_handle, &WebsocketConnection { workspace_id: request.workspace_id.clone(), request_id: request_id.to_string(), ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await?; @@ -261,20 +279,20 @@ pub(crate) async fn connect( Ok(r) => r, Err(e) => { return Ok(upsert_websocket_connection( - &window, + &app_handle, &WebsocketConnection { error: Some(format!("{e:?}")), state: WebsocketConnectionState::Closed, ..connection }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await?); } }; upsert_websocket_event( - &window, + &app_handle, WebsocketEvent { connection_id: connection.id.clone(), request_id: request.id.clone(), @@ -283,7 +301,7 @@ pub(crate) async fn connect( message_type: WebsocketEventType::Open, ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -298,7 +316,7 @@ pub(crate) async fn connect( .collect::>(); let connection = upsert_websocket_connection( - &window, + &app_handle, &WebsocketConnection { state: WebsocketConnectionState::Connected, headers: response_headers, @@ -306,7 +324,7 @@ pub(crate) async fn connect( url: request.url.clone(), ..connection }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await?; @@ -314,7 +332,6 @@ pub(crate) async fn connect( let connection_id = connection.id.clone(); let request_id = request.id.to_string(); let workspace_id = request.workspace_id.clone(); - let window = window.clone(); let connection = connection.clone(); let mut has_written_close = false; tokio::spawn(async move { @@ -324,7 +341,7 @@ pub(crate) async fn connect( } upsert_websocket_event( - &window, + &app_handle, WebsocketEvent { connection_id: connection_id.clone(), request_id: request_id.clone(), @@ -342,7 +359,7 @@ pub(crate) async fn connect( message: message.into_data().into(), ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); @@ -350,7 +367,7 @@ pub(crate) async fn connect( info!("Websocket connection closed"); if !has_written_close { upsert_websocket_event( - &window, + &app_handle, WebsocketEvent { connection_id: connection_id.clone(), request_id: request_id.clone(), @@ -359,20 +376,20 @@ pub(crate) async fn connect( message_type: WebsocketEventType::Close, ..Default::default() }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); } upsert_websocket_connection( - &window, + &app_handle, &WebsocketConnection { workspace_id: request.workspace_id.clone(), request_id: request_id.to_string(), state: WebsocketConnectionState::Closed, ..connection }, - &UpdateSource::Window, + &UpdateSource::from_window(&window), ) .await .unwrap(); diff --git a/src-web/components/GrpcConnectionSetupPane.tsx b/src-web/components/GrpcConnectionSetupPane.tsx index c5436e25a..efc9015dd 100644 --- a/src-web/components/GrpcConnectionSetupPane.tsx +++ b/src-web/components/GrpcConnectionSetupPane.tsx @@ -1,12 +1,11 @@ import type { GrpcMetadataEntry, GrpcRequest } from '@yaakapp-internal/models'; import classNames from 'classnames'; -import { useAtom } from 'jotai'; -import { atomWithStorage } from 'jotai/utils'; import type { CSSProperties } from 'react'; import React, { useCallback, useMemo, useRef } from 'react'; import { useContainerSize } from '../hooks/useContainerQuery'; import type { ReflectResponseService } from '../hooks/useGrpc'; import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication'; +import { useKeyValue } from '../hooks/useKeyValue'; import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey'; import { useUpdateAnyGrpcRequest } from '../hooks/useUpdateAnyGrpcRequest'; import { resolvedModelName } from '../lib/resolvedModelName'; @@ -52,8 +51,6 @@ const TAB_METADATA = 'metadata'; const TAB_AUTH = 'auth'; const TAB_DESCRIPTION = 'description'; -const tabsAtom = atomWithStorage>('grpcRequestPaneActiveTabs', {}); - export function GrpcConnectionSetupPane({ style, services, @@ -70,7 +67,11 @@ export function GrpcConnectionSetupPane({ }: Props) { const updateRequest = useUpdateAnyGrpcRequest(); const authentication = useHttpAuthenticationSummaries(); - const [activeTabs, setActiveTabs] = useAtom(tabsAtom); + const { value: activeTabs, set: setActiveTabs } = useKeyValue>({ + namespace: 'no_sync', + key: 'grpcRequestActiveTabs', + fallback: {}, + }); const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null); const urlContainerEl = useRef(null); @@ -183,8 +184,8 @@ export function GrpcConnectionSetupPane({ const activeTab = activeTabs?.[activeRequest.id]; const setActiveTab = useCallback( - (tab: string) => { - setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab })); + async (tab: string) => { + await setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab })); }, [activeRequest.id, setActiveTabs], ); diff --git a/src-web/components/HttpRequestPane.tsx b/src-web/components/HttpRequestPane.tsx index a7872be15..38c88ba6d 100644 --- a/src-web/components/HttpRequestPane.tsx +++ b/src-web/components/HttpRequestPane.tsx @@ -1,8 +1,7 @@ import type { HttpRequest } from '@yaakapp-internal/models'; import type { GenericCompletionOption } from '@yaakapp-internal/plugins'; import classNames from 'classnames'; -import { atom, useAtom, useAtomValue } from 'jotai'; -import { atomWithStorage } from 'jotai/utils'; +import { atom, useAtomValue } from 'jotai'; import type { CSSProperties } from 'react'; import React, { useCallback, useMemo, useState } from 'react'; import { activeRequestIdAtom } from '../hooks/useActiveRequestId'; @@ -11,6 +10,7 @@ import { grpcRequestsAtom } from '../hooks/useGrpcRequests'; import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication'; import { httpRequestsAtom } from '../hooks/useHttpRequests'; import { useImportCurl } from '../hooks/useImportCurl'; +import { useKeyValue } from '../hooks/useKeyValue'; import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse'; import { useRequestEditor, useRequestEditorEvent } from '../hooks/useRequestEditor'; import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey'; @@ -27,7 +27,8 @@ import { BODY_TYPE_JSON, BODY_TYPE_NONE, BODY_TYPE_OTHER, - BODY_TYPE_XML, getContentTypeFromHeaders, + BODY_TYPE_XML, + getContentTypeFromHeaders, } from '../lib/model_util'; import { prepareImportQuerystring } from '../lib/prepareImportQuerystring'; import { resolvedModelName } from '../lib/resolvedModelName'; @@ -64,8 +65,6 @@ const TAB_HEADERS = 'headers'; const TAB_AUTH = 'auth'; const TAB_DESCRIPTION = 'description'; -const tabsAtom = atomWithStorage>('requestPaneActiveTabs', {}); - const nonActiveRequestUrlsAtom = atom((get) => { const activeRequestId = get(activeRequestIdAtom); const requests = [...get(httpRequestsAtom), ...get(grpcRequestsAtom)]; @@ -79,7 +78,11 @@ const memoNotActiveRequestUrlsAtom = deepEqualAtom(nonActiveRequestUrlsAtom); export function HttpRequestPane({ style, fullHeight, className, activeRequest }: Props) { const activeRequestId = activeRequest.id; const { mutateAsync: updateRequestAsync, mutate: updateRequest } = useUpdateAnyHttpRequest(); - const [activeTabs, setActiveTabs] = useAtom(tabsAtom); + const { value: activeTabs, set: setActiveTabs } = useKeyValue>({ + namespace: 'no_sync', + key: 'httpRequestActiveTabs', + fallback: {}, + }); const [forceUpdateHeaderEditorKey, setForceUpdateHeaderEditorKey] = useState(0); const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null); const [{ urlKey }, { focusParamsTab, forceUrlRefresh, forceParamsRefresh }] = useRequestEditor(); @@ -285,14 +288,14 @@ export function HttpRequestPane({ style, fullHeight, className, activeRequest }: const activeTab = activeTabs?.[activeRequestId]; const setActiveTab = useCallback( - (tab: string) => { - setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab })); + async (tab: string) => { + await setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab })); }, [activeRequest.id, setActiveTabs], ); - useRequestEditorEvent('request_pane.focus_tab', () => { - setActiveTab(TAB_PARAMS); + useRequestEditorEvent('request_pane.focus_tab', async () => { + await setActiveTab(TAB_PARAMS); }); const autocompleteUrls = useAtomValue(memoNotActiveRequestUrlsAtom); diff --git a/src-web/components/WebsocketRequestPane.tsx b/src-web/components/WebsocketRequestPane.tsx index bd26e5a77..a56e76322 100644 --- a/src-web/components/WebsocketRequestPane.tsx +++ b/src-web/components/WebsocketRequestPane.tsx @@ -2,8 +2,7 @@ import type { HttpRequest, WebsocketRequest } from '@yaakapp-internal/models'; import type { GenericCompletionOption } from '@yaakapp-internal/plugins'; import { closeWebsocket, connectWebsocket, sendWebsocket } from '@yaakapp-internal/ws'; import classNames from 'classnames'; -import { atom, useAtom, useAtomValue } from 'jotai'; -import { atomWithStorage } from 'jotai/utils'; +import { atom, useAtomValue } from 'jotai'; import type { CSSProperties } from 'react'; import React, { useCallback, useMemo } from 'react'; import { upsertWebsocketRequest } from '../commands/upsertWebsocketRequest'; @@ -12,6 +11,7 @@ import { getActiveEnvironment } from '../hooks/useActiveEnvironment'; import { activeRequestIdAtom } from '../hooks/useActiveRequestId'; import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse'; import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication'; +import { useKeyValue } from '../hooks/useKeyValue'; import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse'; import { useRequestEditor, useRequestEditorEvent } from '../hooks/useRequestEditor'; import { requestsAtom } from '../hooks/useRequests'; @@ -50,8 +50,6 @@ const TAB_HEADERS = 'headers'; const TAB_AUTH = 'auth'; const TAB_DESCRIPTION = 'description'; -const tabsAtom = atomWithStorage>('requestPaneActiveTabs', {}); - const nonActiveRequestUrlsAtom = atom((get) => { const activeRequestId = get(activeRequestIdAtom); const requests = get(requestsAtom); @@ -64,7 +62,11 @@ const memoNotActiveRequestUrlsAtom = deepEqualAtom(nonActiveRequestUrlsAtom); export function WebsocketRequestPane({ style, fullHeight, className, activeRequest }: Props) { const activeRequestId = activeRequest.id; - const [activeTabs, setActiveTabs] = useAtom(tabsAtom); + const { value: activeTabs, set: setActiveTabs } = useKeyValue>({ + namespace: 'no_sync', + key: 'websocketRequestActiveTabs', + fallback: {}, + }); const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null); const [{ urlKey }, { focusParamsTab, forceUrlRefresh, forceParamsRefresh }] = useRequestEditor(); const authentication = useHttpAuthenticationSummaries(); @@ -157,14 +159,14 @@ export function WebsocketRequestPane({ style, fullHeight, className, activeReque const activeTab = activeTabs?.[activeRequestId]; const setActiveTab = useCallback( - (tab: string) => { - setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab })); + async (tab: string) => { + await setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab })); }, [activeRequest.id, setActiveTabs], ); - useRequestEditorEvent('request_pane.focus_tab', () => { - setActiveTab(TAB_PARAMS); + useRequestEditorEvent('request_pane.focus_tab', async () => { + await setActiveTab(TAB_PARAMS); }); const autocompleteUrls = useAtomValue(memoNotActiveRequestUrlsAtom); diff --git a/src-web/hooks/useSyncModelStores.ts b/src-web/hooks/useSyncModelStores.ts index ed677a1b8..bc9d51f24 100644 --- a/src-web/hooks/useSyncModelStores.ts +++ b/src-web/hooks/useSyncModelStores.ts @@ -5,7 +5,7 @@ import type { AnyModel, KeyValue, ModelPayload } from '@yaakapp-internal/models' import { jotaiStore } from '../lib/jotai'; import { buildKeyValueKey } from '../lib/keyValueStore'; import { modelsEq } from '../lib/model_util'; -import { useActiveWorkspace } from './useActiveWorkspace'; +import { getActiveWorkspaceId } from './useActiveWorkspace'; import { cookieJarsAtom } from './useCookieJars'; import { environmentsAtom } from './useEnvironments'; import { foldersAtom } from './useFolders'; @@ -26,7 +26,6 @@ import { workspaceMetaAtom } from './useWorkspaceMeta'; import { workspacesAtom } from './useWorkspaces'; export function useSyncModelStores() { - const activeWorkspace = useActiveWorkspace(); const queryClient = useQueryClient(); const { wasUpdatedExternally } = useRequestUpdateKey(null); @@ -45,16 +44,13 @@ export function useSyncModelStores() { (payload.model.model === 'http_request' || payload.model.model === 'grpc_request' || payload.model.model === 'websocket_request') && - (payload.windowLabel !== getCurrentWebviewWindow().label || payload.updateSource !== 'window') + ((payload.updateSource.type === 'window' && + payload.updateSource.label !== getCurrentWebviewWindow().label) || + payload.updateSource.type !== 'window') ) { wasUpdatedExternally(payload.model.id); } - // Only sync models that belong to this workspace, if a workspace ID is present - if ('workspaceId' in payload.model && payload.model.workspaceId !== activeWorkspace?.id) { - return; - } - if (shouldIgnoreModel(payload)) return; if (payload.model.model === 'workspace') { @@ -160,7 +156,7 @@ export function removeModelById(model: T) { return (prevEntries: T[] | undefined) => { const entries = prevEntries?.filter((e) => e.id !== model.id) ?? []; - // Don't trigger an update if we didn't actually remove anything + // Don't trigger an update if we didn't remove anything if (entries.length === (prevEntries ?? []).length) { return prevEntries ?? []; } @@ -181,17 +177,24 @@ export function removeModelByKv(model: KeyValue) { ) ?? []; } -function shouldIgnoreModel({ model, windowLabel, updateSource }: ModelPayload) { - // Never ignore same-window updates - if (windowLabel === getCurrentWebviewWindow().label) { +function shouldIgnoreModel({ model, updateSource }: ModelPayload) { + console.log('HELLO', updateSource); + // Never ignore updates from non-user sources + if (updateSource.type !== 'window') { return false; } - // Never ignore updates from non-user sources - if (updateSource !== 'window') { + // Never ignore same-window updates + if (updateSource.label === getCurrentWebviewWindow().label) { return false; } + const activeWorkspaceId = getActiveWorkspaceId(); + // Only sync models that belong to this workspace, if a workspace ID is present + if ('workspaceId' in model && model.workspaceId !== activeWorkspaceId) { + return; + } + if (model.model === 'key_value') { return model.namespace === 'no_sync'; } From d86549f4920b463cf6bfaf01534f03c77bdf3c29 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 21 Mar 2025 07:28:08 -0700 Subject: [PATCH 116/996] Always show GQL schema dropdown. Fixes https://feedback.yaak.app/p/unable-to-disable-graphql-automatic-introspection --- src-web/components/GraphQLEditor.tsx | 82 +++++++++++++++------------ src-web/components/core/Dropdown.tsx | 10 +++- src-web/hooks/useIntrospectGraphQL.ts | 3 +- 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src-web/components/GraphQLEditor.tsx b/src-web/components/GraphQLEditor.tsx index fd34b55c8..aac0b28c8 100644 --- a/src-web/components/GraphQLEditor.tsx +++ b/src-web/components/GraphQLEditor.tsx @@ -7,6 +7,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'; import { useLocalStorage } from 'react-use'; import { useIntrospectGraphQL } from '../hooks/useIntrospectGraphQL'; import { showDialog } from '../lib/dialog'; +import { Banner } from './core/Banner'; import { Button } from './core/Button'; import { Dropdown } from './core/Dropdown'; import type { EditorProps } from './core/Editor/Editor'; @@ -64,9 +65,50 @@ export function GraphQLEditor({ request, onChange, baseRequest, ...extraEditorPr const actions = useMemo( () => [

- {schema === undefined ? null /* Initializing */ : !error ? ( + {schema === undefined ? null /* Initializing */ : ( +

Schema introspection failed

+ +
+ + ), + }); + }} + > + View Error + + + ), + type: 'content', + }, { label: 'Refetch', leftSlot: , @@ -105,44 +147,12 @@ export function GraphQLEditor({ request, onChange, baseRequest, ...extraEditorPr variant="border" title="Refetch Schema" isLoading={isLoading} - color={isLoading || schema ? 'default' : 'warning'} + color={error ? 'danger' : 'default'} + forDropdown > - {isLoading ? 'Introspecting' : schema ? 'Schema' : 'No Schema'} + {error ? 'Introspection Failed' : schema ? 'Schema' : 'No Schema'} - ) : ( - -
- - ), - }); - }} - > - Introspection Failed - )}
, ], diff --git a/src-web/components/core/Dropdown.tsx b/src-web/components/core/Dropdown.tsx index 0c4f20dd8..97f6349a3 100644 --- a/src-web/components/core/Dropdown.tsx +++ b/src-web/components/core/Dropdown.tsx @@ -558,7 +558,15 @@ const Menu = forwardRef + // eslint-disable-next-line jsx-a11y/no-static-element-interactions,jsx-a11y/click-events-have-key-events +
{ + // Ensure the dropdown is closed when anything in the content is clicked + onClose(); + }} + > {item.label}
); diff --git a/src-web/hooks/useIntrospectGraphQL.ts b/src-web/hooks/useIntrospectGraphQL.ts index 58814e40d..02f97bc3d 100644 --- a/src-web/hooks/useIntrospectGraphQL.ts +++ b/src-web/hooks/useIntrospectGraphQL.ts @@ -51,7 +51,7 @@ export function useIntrospectGraphQL( const bodyText = await getResponseBodyText(response); if (response.status < 200 || response.status >= 300) { - return setError(`Request failed with status ${response.status}.\n\n${bodyText}`); + return setError(`Request failed with status ${response.status}.\nThe response body is:\n\n${bodyText}`); } if (bodyText === null) { @@ -80,6 +80,7 @@ export function useIntrospectGraphQL( }, [request.id, request.url, request.method, activeEnvironment?.id]); const clear = useCallback(async () => { + setError(''); await setIntrospection(null); }, [setIntrospection]); From 5fedea38c26979fa2ad08fa9c225e7fbc190c977 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 21 Mar 2025 07:42:05 -0700 Subject: [PATCH 117/996] Fix lint error --- src-tauri/src/lib.rs | 2 +- src-tauri/src/plugin_events.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index b275ce1a0..e647c784f 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1973,7 +1973,7 @@ pub fn run() { .run(|app_handle, event| { match event { RunEvent::Ready => { - let w = window::create_main_window(app_handle, "/"); + let _ = window::create_main_window(app_handle, "/"); let h = app_handle.clone(); tauri::async_runtime::spawn(async move { let info = history::store_launch_history(&h).await; diff --git a/src-tauri/src/plugin_events.rs b/src-tauri/src/plugin_events.rs index 8da381c30..5a680c461 100644 --- a/src-tauri/src/plugin_events.rs +++ b/src-tauri/src/plugin_events.rs @@ -18,8 +18,8 @@ use yaak_models::queries::{ use yaak_plugins::events::{ Color, DeleteKeyValueResponse, EmptyPayload, FindHttpResponsesResponse, GetHttpRequestByIdResponse, GetKeyValueResponse, Icon, InternalEvent, InternalEventPayload, - RenderHttpRequestResponse, RenderPurpose, SendHttpRequestResponse, SetKeyValueResponse, - ShowToastRequest, TemplateRenderResponse, WindowContext, WindowNavigateEvent, + RenderHttpRequestResponse, SendHttpRequestResponse, SetKeyValueResponse, ShowToastRequest, + TemplateRenderResponse, WindowContext, WindowNavigateEvent, }; use yaak_plugins::manager::PluginManager; use yaak_plugins::plugin_handle::PluginHandle; From 445c30f3a99d01f05535aff6194a7aa12f0decc1 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 23 Mar 2025 06:57:36 -0700 Subject: [PATCH 118/996] Fix iframe scrollbar --- src-web/main.css | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src-web/main.css b/src-web/main.css index 8a053e235..5e7a4b374 100644 --- a/src-web/main.css +++ b/src-web/main.css @@ -66,22 +66,31 @@ * Mac doesn't like this (especially in CodeMirror) so we only do it on non-macos platforms. On Mac, * styling the scrollbar seems to cause them to not show up at all most of the time */ - html:not([data-platform="macos"]) * { - ::-webkit-scrollbar-corner, - ::-webkit-scrollbar { - @apply w-[10px] h-[10px]; - } + html:not([data-platform="macos"]) { + * { + ::-webkit-scrollbar-corner, + ::-webkit-scrollbar { + @apply w-[10px] h-[10px]; + } - .scrollbar-track, - ::-webkit-scrollbar-corner, - ::-webkit-scrollbar { - @apply bg-transparent; + .scrollbar-track, + ::-webkit-scrollbar-corner, + ::-webkit-scrollbar { + @apply bg-transparent; + } + + &:hover { + &.scrollbar-thumb, + &::-webkit-scrollbar-thumb { + @apply bg-text-subtlest hover:bg-text-subtle rounded-[2px]; + } + } } - &:hover { - &.scrollbar-thumb, - &::-webkit-scrollbar-thumb { - @apply bg-text-subtlest hover:bg-text-subtle rounded-[2px]; + iframe { + &::-webkit-scrollbar-corner, + &::-webkit-scrollbar { + @apply bg-surface-highlight !important; } } } @@ -90,13 +99,6 @@ direction: rtl; } - iframe { - &::-webkit-scrollbar-corner, - &::-webkit-scrollbar { - @apply bg-surface-highlight !important; - } - } - :root { color-scheme: light dark; --transition-duration: 100ms ease-in-out; From 1d37d461304586f3002dae146897556f9c06a0f9 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 25 Mar 2025 08:35:10 -0700 Subject: [PATCH 119/996] Database access refactor (#190) --- package-lock.json | 232 +- package.json | 8 +- packages/plugin-runtime-types/package.json | 4 +- packages/plugin-runtime/src/PluginHandle.ts | 1 - src-tauri/Cargo.lock | 460 ++- src-tauri/Cargo.toml | 6 +- src-tauri/gen/schemas/acl-manifests.json | 2 +- src-tauri/gen/schemas/desktop-schema.json | 91 +- src-tauri/gen/schemas/macOS-schema.json | 91 +- src-tauri/src/error.rs | 17 +- src-tauri/src/history.rs | 48 +- src-tauri/src/http_request.rs | 62 +- src-tauri/src/lib.rs | 1101 +++---- src-tauri/src/notifications.rs | 26 +- src-tauri/src/plugin_events.rs | 104 +- src-tauri/src/updates.rs | 58 +- src-tauri/yaak-git/Cargo.toml | 4 +- .../yaak-git/permissions/schemas/schema.json | 4 +- .../permissions/schemas/schema.json | 4 +- src-tauri/yaak-license/src/commands.rs | 8 +- src-tauri/yaak-license/src/error.rs | 3 + src-tauri/yaak-license/src/license.rs | 32 +- src-tauri/yaak-models/Cargo.toml | 5 + src-tauri/yaak-models/bindings/gen_models.ts | 8 +- src-tauri/yaak-models/build.rs | 5 + .../autogenerated/commands/delete.toml | 13 + .../autogenerated/commands/delete_model.toml | 13 + .../autogenerated/commands/upsert.toml | 13 + .../autogenerated/commands/upsert_model.toml | 13 + .../permissions/autogenerated/reference.md | 120 + .../yaak-models/permissions/default.toml | 6 + .../permissions/schemas/schema.json | 345 ++ src-tauri/yaak-models/src/commands.rs | 24 + src-tauri/yaak-models/src/error.rs | 21 +- src-tauri/yaak-models/src/lib.rs | 97 +- src-tauri/yaak-models/src/manager.rs | 122 +- src-tauri/yaak-models/src/models.rs | 1588 ++++++---- src-tauri/yaak-models/src/plugin.rs | 81 - src-tauri/yaak-models/src/queries.rs | 2761 ----------------- src-tauri/yaak-models/src/queries/base.rs | 169 + src-tauri/yaak-models/src/queries/batch.rs | 99 + .../yaak-models/src/queries/cookie_jars.rs | 35 + .../yaak-models/src/queries/environments.rs | 79 + src-tauri/yaak-models/src/queries/folders.rs | 106 + .../src/queries/grpc_connections.rs | 98 + .../yaak-models/src/queries/grpc_events.rs | 22 + .../yaak-models/src/queries/grpc_requests.rs | 51 + .../yaak-models/src/queries/http_requests.rs | 51 + .../yaak-models/src/queries/http_responses.rs | 110 + .../yaak-models/src/queries/key_values.rs | 164 + src-tauri/yaak-models/src/queries/mod.rs | 20 + .../src/queries/plugin_key_values.rs | 79 + src-tauri/yaak-models/src/queries/plugins.rs | 27 + src-tauri/yaak-models/src/queries/settings.rs | 25 + .../yaak-models/src/queries/sync_states.rs | 45 + .../src/queries/websocket_connections.rs | 97 + .../src/queries/websocket_events.rs | 25 + .../src/queries/websocket_requests.rs | 51 + .../src/queries/workspace_metas.rs | 36 + .../yaak-models/src/queries/workspaces.rs | 52 + src-tauri/yaak-models/src/queries_legacy.rs | 150 + src-tauri/yaak-plugins/src/manager.rs | 40 +- .../yaak-sync/permissions/schemas/schema.json | 4 +- src-tauri/yaak-sync/src/models.rs | 3 +- src-tauri/yaak-sync/src/sync.rs | 91 +- .../yaak-ws/permissions/schemas/schema.json | 4 +- src-tauri/yaak-ws/src/commands.rs | 246 +- src-web/components/HttpResponsePane.tsx | 1 + src-web/hooks/useCreateHttpRequest.ts | 2 +- src-web/hooks/useSyncModelStores.ts | 1 - src-web/hooks/useUpdateAnyHttpRequest.ts | 2 +- src-web/lib/tauri.ts | 3 +- 72 files changed, 4891 insertions(+), 4698 deletions(-) create mode 100644 src-tauri/yaak-models/build.rs create mode 100644 src-tauri/yaak-models/permissions/autogenerated/commands/delete.toml create mode 100644 src-tauri/yaak-models/permissions/autogenerated/commands/delete_model.toml create mode 100644 src-tauri/yaak-models/permissions/autogenerated/commands/upsert.toml create mode 100644 src-tauri/yaak-models/permissions/autogenerated/commands/upsert_model.toml create mode 100644 src-tauri/yaak-models/permissions/autogenerated/reference.md create mode 100644 src-tauri/yaak-models/permissions/default.toml create mode 100644 src-tauri/yaak-models/permissions/schemas/schema.json create mode 100644 src-tauri/yaak-models/src/commands.rs delete mode 100644 src-tauri/yaak-models/src/plugin.rs delete mode 100644 src-tauri/yaak-models/src/queries.rs create mode 100644 src-tauri/yaak-models/src/queries/base.rs create mode 100644 src-tauri/yaak-models/src/queries/batch.rs create mode 100644 src-tauri/yaak-models/src/queries/cookie_jars.rs create mode 100644 src-tauri/yaak-models/src/queries/environments.rs create mode 100644 src-tauri/yaak-models/src/queries/folders.rs create mode 100644 src-tauri/yaak-models/src/queries/grpc_connections.rs create mode 100644 src-tauri/yaak-models/src/queries/grpc_events.rs create mode 100644 src-tauri/yaak-models/src/queries/grpc_requests.rs create mode 100644 src-tauri/yaak-models/src/queries/http_requests.rs create mode 100644 src-tauri/yaak-models/src/queries/http_responses.rs create mode 100644 src-tauri/yaak-models/src/queries/key_values.rs create mode 100644 src-tauri/yaak-models/src/queries/mod.rs create mode 100644 src-tauri/yaak-models/src/queries/plugin_key_values.rs create mode 100644 src-tauri/yaak-models/src/queries/plugins.rs create mode 100644 src-tauri/yaak-models/src/queries/settings.rs create mode 100644 src-tauri/yaak-models/src/queries/sync_states.rs create mode 100644 src-tauri/yaak-models/src/queries/websocket_connections.rs create mode 100644 src-tauri/yaak-models/src/queries/websocket_events.rs create mode 100644 src-tauri/yaak-models/src/queries/websocket_requests.rs create mode 100644 src-tauri/yaak-models/src/queries/workspace_metas.rs create mode 100644 src-tauri/yaak-models/src/queries/workspaces.rs create mode 100644 src-tauri/yaak-models/src/queries_legacy.rs diff --git a/package-lock.json b/package-lock.json index 986132534..56c3d059a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,9 +22,9 @@ "src-web" ], "devDependencies": { - "@tauri-apps/cli": "^2.2.7", - "@typescript-eslint/eslint-plugin": "^8.18.1", - "@typescript-eslint/parser": "^8.18.1", + "@tauri-apps/cli": "^2.4.0", + "@typescript-eslint/eslint-plugin": "^8.27.0", + "@typescript-eslint/parser": "^8.27.0", "eslint": "^8", "eslint-config-prettier": "^8", "eslint-plugin-import": "^2.31.0", @@ -34,7 +34,7 @@ "nodejs-file-downloader": "^4.13.0", "npm-run-all": "^4.1.5", "prettier": "^3.4.2", - "typescript": "^5.7.2" + "typescript": "^5.8.2" } }, "node_modules/@alloc/quick-lru": { @@ -2782,9 +2782,9 @@ } }, "node_modules/@tauri-apps/cli": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.2.7.tgz", - "integrity": "sha512-ZnsS2B4BplwXP37celanNANiIy8TCYhvg5RT09n72uR/o+navFZtGpFSqljV8fy1Y4ixIPds8FrGSXJCN2BerA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.4.0.tgz", + "integrity": "sha512-Esg7s20tuSULd2YF3lmtMa1vF7yr5eh/TlBHXjEyrC+XSD9aBxHVoXb6oz7oKybDY9Jf9OiBa0bf2PbybcmOLA==", "dev": true, "license": "Apache-2.0 OR MIT", "bin": { @@ -2798,22 +2798,23 @@ "url": "https://opencollective.com/tauri" }, "optionalDependencies": { - "@tauri-apps/cli-darwin-arm64": "2.2.7", - "@tauri-apps/cli-darwin-x64": "2.2.7", - "@tauri-apps/cli-linux-arm-gnueabihf": "2.2.7", - "@tauri-apps/cli-linux-arm64-gnu": "2.2.7", - "@tauri-apps/cli-linux-arm64-musl": "2.2.7", - "@tauri-apps/cli-linux-x64-gnu": "2.2.7", - "@tauri-apps/cli-linux-x64-musl": "2.2.7", - "@tauri-apps/cli-win32-arm64-msvc": "2.2.7", - "@tauri-apps/cli-win32-ia32-msvc": "2.2.7", - "@tauri-apps/cli-win32-x64-msvc": "2.2.7" + "@tauri-apps/cli-darwin-arm64": "2.4.0", + "@tauri-apps/cli-darwin-x64": "2.4.0", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.4.0", + "@tauri-apps/cli-linux-arm64-gnu": "2.4.0", + "@tauri-apps/cli-linux-arm64-musl": "2.4.0", + "@tauri-apps/cli-linux-riscv64-gnu": "2.4.0", + "@tauri-apps/cli-linux-x64-gnu": "2.4.0", + "@tauri-apps/cli-linux-x64-musl": "2.4.0", + "@tauri-apps/cli-win32-arm64-msvc": "2.4.0", + "@tauri-apps/cli-win32-ia32-msvc": "2.4.0", + "@tauri-apps/cli-win32-x64-msvc": "2.4.0" } }, "node_modules/@tauri-apps/cli-darwin-arm64": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.2.7.tgz", - "integrity": "sha512-54kcpxZ3X1Rq+pPTzk3iIcjEVY4yv493uRx/80rLoAA95vAC0c//31Whz75UVddDjJfZvXlXZ3uSZ+bnCOnt0A==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.4.0.tgz", + "integrity": "sha512-MVzYrahJBgDyzUJ2gNEU8H+0oCVEucN115+CVorFnidHcJ6DtDRMCaKLkpjOZNfJyag1WQ25fu7imvZSe0mz/g==", "cpu": [ "arm64" ], @@ -2828,9 +2829,9 @@ } }, "node_modules/@tauri-apps/cli-darwin-x64": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.2.7.tgz", - "integrity": "sha512-Vgu2XtBWemLnarB+6LqQeLanDlRj7CeFN//H8bVVdjbNzxcSxsvbLYMBP8+3boa7eBnjDrqMImRySSgL6IrwTw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.4.0.tgz", + "integrity": "sha512-/4IdbWv6IWSuBn0WVe5JkiSIP1gZhXCZRcumSsYq3ZmOlq4BqXeXT36Oig5mlDnS/2/UpNS94kd8gOA1DNdIeQ==", "cpu": [ "x64" ], @@ -2845,9 +2846,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.2.7.tgz", - "integrity": "sha512-+Clha2iQAiK9zoY/KKW0KLHkR0k36O78YLx5Sl98tWkwI3OBZFg5H5WT1plH/4sbZIS2aLFN6dw58/JlY9Bu/g==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.4.0.tgz", + "integrity": "sha512-rOjlk3Vd6R847LXds4pOAFKUL5NVdSWlaiQvr4H9WDUwIWWoxnj7SQfpryTtElDb2wV7a0BNaOCXCpyFEAXjkw==", "cpu": [ "arm" ], @@ -2862,9 +2863,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm64-gnu": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.2.7.tgz", - "integrity": "sha512-Z/Lp4SQe6BUEOays9BQAEum2pvZF4w9igyXijP+WbkOejZx4cDvarFJ5qXrqSLmBh7vxrdZcLwoLk9U//+yQrg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.4.0.tgz", + "integrity": "sha512-X/uCwao6R/weWT2y4f3JKJMeUsujo9H4nBMAv9RZhRsz93n9Amw9ETavAOP11pyhl57YkasvKTCRQN6FwsaoXg==", "cpu": [ "arm64" ], @@ -2879,9 +2880,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm64-musl": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.7.tgz", - "integrity": "sha512-+8HZ+txff/Y3YjAh80XcLXcX8kpGXVdr1P8AfjLHxHdS6QD4Md+acSxGTTNbplmHuBaSHJvuTvZf9tU1eDCTDg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.0.tgz", + "integrity": "sha512-GhvQtrTjadW3eLSmfrSfybSqgJMZzUXC+0WqDzFovLug3a1a1go0m9QK9YGvYLkyEpTY5zRxLtwv+tbZXN4tZw==", "cpu": [ "arm64" ], @@ -2895,10 +2896,27 @@ "node": ">= 10" } }, + "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.4.0.tgz", + "integrity": "sha512-NgeNihQ9uHS/ibMWLge5VA/BgsS/g8VPSVtCp8DSPyub3bBuCy79A8V+bzNKlMOiDVrqK4vQ//FS9kSxoJOtXw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@tauri-apps/cli-linux-x64-gnu": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.2.7.tgz", - "integrity": "sha512-ahlSnuCnUntblp9dG7/w5ZWZOdzRFi3zl0oScgt7GF4KNAOEa7duADsxPA4/FT2hLRa0SvpqtD4IYFvCxoVv3Q==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.4.0.tgz", + "integrity": "sha512-ebRmV2HLIVms1KlNNueQCp3OrXBv6cimU3mYEh5NbZ8dH88f2sF46dFCyPq8Qr/Zti4qPEaAArVG7RYFjfECPw==", "cpu": [ "x64" ], @@ -2913,9 +2931,9 @@ } }, "node_modules/@tauri-apps/cli-linux-x64-musl": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.7.tgz", - "integrity": "sha512-+qKAWnJRSX+pjjRbKAQgTdFY8ecdcu8UdJ69i7wn3ZcRn2nMMzOO2LOMOTQV42B7/Q64D1pIpmZj9yblTMvadA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.0.tgz", + "integrity": "sha512-FOp2cBFyq5LnUr3he95Z99PQm3nCSJv2GZNeH7UqmUpeHwdcYuhBERU7C+8VDJJPR98Q5fkcoV00Pc4nw0v5KQ==", "cpu": [ "x64" ], @@ -2930,9 +2948,9 @@ } }, "node_modules/@tauri-apps/cli-win32-arm64-msvc": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.2.7.tgz", - "integrity": "sha512-aa86nRnrwT04u9D9fhf5JVssuAZlUCCc8AjqQjqODQjMd4BMA2+d4K9qBMpEG/1kVh95vZaNsLogjEaqSTTw4A==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.4.0.tgz", + "integrity": "sha512-SVf1wDagYsaFM+mpUYKmjNveKodcUSGPEM27WmMW4Enh6aXGzTJi4IYOE3GEFOJF1BpRNscslwE1Rd064kfpcg==", "cpu": [ "arm64" ], @@ -2947,9 +2965,9 @@ } }, "node_modules/@tauri-apps/cli-win32-ia32-msvc": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.2.7.tgz", - "integrity": "sha512-EiJ5/25tLSQOSGvv+t6o3ZBfOTKB5S3vb+hHQuKbfmKdRF0XQu2YPdIi1CQw1DU97ZAE0Dq4frvnyYEKWgMzVQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.4.0.tgz", + "integrity": "sha512-j+fOFVeSSejk9hrUePY7bJuaYr+80xr+ftjXzxCj0CS0d2oSbq+lT8/zS514WemJk9e9yxUus+2ke/Ng17wkkQ==", "cpu": [ "ia32" ], @@ -2964,9 +2982,9 @@ } }, "node_modules/@tauri-apps/cli-win32-x64-msvc": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.2.7.tgz", - "integrity": "sha512-ZB8Kw90j8Ld+9tCWyD2fWCYfIrzbQohJ4DJSidNwbnehlZzP7wAz6Z3xjsvUdKtQ3ibtfoeTqVInzCCEpI+pWg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.4.0.tgz", + "integrity": "sha512-nv84b3a8eI5Y7ksTLBKjjvtr9NOlAGGGo7OJbjKT+xZLdiPOZ0nJ2cT+4IdfnNAZ33pKJugAfuj1fBvQKeTy0w==", "cpu": [ "x64" ], @@ -3296,21 +3314,21 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.1.tgz", - "integrity": "sha512-Ncvsq5CT3Gvh+uJG0Lwlho6suwDfUXH0HztslDf5I+F2wAFAZMRwYLEorumpKLzmO2suAXZ/td1tBg4NZIi9CQ==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.27.0.tgz", + "integrity": "sha512-4henw4zkePi5p252c8ncBLzLce52SEUz2Ebj8faDnuUXz2UuHEONYcJ+G0oaCF+bYCWVZtrGzq3FD7YXetmnSA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.18.1", - "@typescript-eslint/type-utils": "8.18.1", - "@typescript-eslint/utils": "8.18.1", - "@typescript-eslint/visitor-keys": "8.18.1", + "@typescript-eslint/scope-manager": "8.27.0", + "@typescript-eslint/type-utils": "8.27.0", + "@typescript-eslint/utils": "8.27.0", + "@typescript-eslint/visitor-keys": "8.27.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3322,20 +3340,20 @@ "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.18.1.tgz", - "integrity": "sha512-rBnTWHCdbYM2lh7hjyXqxk70wvon3p2FyaniZuey5TrcGBpfhVp0OxOa6gxr9Q9YhZFKyfbEnxc24ZnVbbUkCA==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.27.0.tgz", + "integrity": "sha512-XGwIabPallYipmcOk45DpsBSgLC64A0yvdAkrwEzwZ2viqGqRUJ8eEYoPz0CWnutgAFbNMPdsGGvzjSmcWVlEA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.18.1", - "@typescript-eslint/types": "8.18.1", - "@typescript-eslint/typescript-estree": "8.18.1", - "@typescript-eslint/visitor-keys": "8.18.1", + "@typescript-eslint/scope-manager": "8.27.0", + "@typescript-eslint/types": "8.27.0", + "@typescript-eslint/typescript-estree": "8.27.0", + "@typescript-eslint/visitor-keys": "8.27.0", "debug": "^4.3.4" }, "engines": { @@ -3347,18 +3365,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.18.1.tgz", - "integrity": "sha512-HxfHo2b090M5s2+/9Z3gkBhI6xBH8OJCFjH9MhQ+nnoZqxU3wNxkLT+VWXWSFWc3UF3Z+CfPAyqdCTdoXtDPCQ==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.27.0.tgz", + "integrity": "sha512-8oI9GwPMQmBryaaxG1tOZdxXVeMDte6NyJA4i7/TWa4fBwgnAXYlIQP+uYOeqAaLJ2JRxlG9CAyL+C+YE9Xknw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.18.1", - "@typescript-eslint/visitor-keys": "8.18.1" + "@typescript-eslint/types": "8.27.0", + "@typescript-eslint/visitor-keys": "8.27.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3369,16 +3387,16 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.18.1.tgz", - "integrity": "sha512-jAhTdK/Qx2NJPNOTxXpMwlOiSymtR2j283TtPqXkKBdH8OAMmhiUfP0kJjc/qSE51Xrq02Gj9NY7MwK+UxVwHQ==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.27.0.tgz", + "integrity": "sha512-wVArTVcz1oJOIEJxui/nRhV0TXzD/zMSOYi/ggCfNq78EIszddXcJb7r4RCp/oBrjt8n9A0BSxRMKxHftpDxDA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.18.1", - "@typescript-eslint/utils": "8.18.1", + "@typescript-eslint/typescript-estree": "8.27.0", + "@typescript-eslint/utils": "8.27.0", "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3389,13 +3407,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.18.1.tgz", - "integrity": "sha512-7uoAUsCj66qdNQNpH2G8MyTFlgerum8ubf21s3TSM3XmKXuIn+H2Sifh/ES2nPOPiYSRJWAk0fDkW0APBWcpfw==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.27.0.tgz", + "integrity": "sha512-/6cp9yL72yUHAYq9g6DsAU+vVfvQmd1a8KyA81uvfDE21O2DwQ/qxlM4AR8TSdAu+kJLBDrEHKC5/W2/nxsY0A==", "dev": true, "license": "MIT", "engines": { @@ -3407,20 +3425,20 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.18.1.tgz", - "integrity": "sha512-z8U21WI5txzl2XYOW7i9hJhxoKKNG1kcU4RzyNvKrdZDmbjkmLBo8bgeiOJmA06kizLI76/CCBAAGlTlEeUfyg==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.27.0.tgz", + "integrity": "sha512-BnKq8cqPVoMw71O38a1tEb6iebEgGA80icSxW7g+kndx0o6ot6696HjG7NdgfuAVmVEtwXUr3L8R9ZuVjoQL6A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.18.1", - "@typescript-eslint/visitor-keys": "8.18.1", + "@typescript-eslint/types": "8.27.0", + "@typescript-eslint/visitor-keys": "8.27.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3430,20 +3448,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.18.1.tgz", - "integrity": "sha512-8vikiIj2ebrC4WRdcAdDcmnu9Q/MXXwg+STf40BVfT8exDqBCUPdypvzcUPxEqRGKg9ALagZ0UWcYCtn+4W2iQ==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.27.0.tgz", + "integrity": "sha512-njkodcwH1yvmo31YWgRHNb/x1Xhhq4/m81PhtvmRngD8iHPehxffz1SNCO+kwaePhATC+kOa/ggmvPoPza5i0Q==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.18.1", - "@typescript-eslint/types": "8.18.1", - "@typescript-eslint/typescript-estree": "8.18.1" + "@typescript-eslint/scope-manager": "8.27.0", + "@typescript-eslint/types": "8.27.0", + "@typescript-eslint/typescript-estree": "8.27.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3454,17 +3472,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.18.1.tgz", - "integrity": "sha512-Vj0WLm5/ZsD013YeUKn+K0y8p1M0jPpxOkKdbD1wB0ns53a5piVY02zjf072TblEweAbcYiFiPoSMF3kp+VhhQ==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.27.0.tgz", + "integrity": "sha512-WsXQwMkILJvffP6z4U3FYJPlbf/j07HIxmDjZpbNvBJkMfvwXj5ACRkkHwBDvLBbDbtX5TdU64/rcvKJ/vuInQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.18.1", + "@typescript-eslint/types": "8.27.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -13842,16 +13860,16 @@ } }, "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/ts-easing": { @@ -14440,9 +14458,9 @@ } }, "node_modules/typescript": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -15562,9 +15580,7 @@ "@types/node": "^22.5.4" }, "devDependencies": { - "cpy-cli": "^5.0.0", - "npm-run-all": "^4.1.5", - "typescript": "^5.6.2" + "cpy-cli": "^5.0.0" } }, "packages/plugin-runtime/node_modules/ws": { diff --git a/package.json b/package.json index 73bc76dfa..6fbb1aafe 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,9 @@ "tauri-before-dev": "npm run --workspaces --if-present dev" }, "devDependencies": { - "@tauri-apps/cli": "^2.2.7", - "@typescript-eslint/eslint-plugin": "^8.18.1", - "@typescript-eslint/parser": "^8.18.1", + "@tauri-apps/cli": "^2.4.0", + "@typescript-eslint/eslint-plugin": "^8.27.0", + "@typescript-eslint/parser": "^8.27.0", "eslint": "^8", "eslint-config-prettier": "^8", "eslint-plugin-import": "^2.31.0", @@ -48,6 +48,6 @@ "nodejs-file-downloader": "^4.13.0", "npm-run-all": "^4.1.5", "prettier": "^3.4.2", - "typescript": "^5.7.2" + "typescript": "^5.8.2" } } diff --git a/packages/plugin-runtime-types/package.json b/packages/plugin-runtime-types/package.json index e376f5e93..5b6ee95f7 100644 --- a/packages/plugin-runtime-types/package.json +++ b/packages/plugin-runtime-types/package.json @@ -20,8 +20,6 @@ "@types/node": "^22.5.4" }, "devDependencies": { - "cpy-cli": "^5.0.0", - "npm-run-all": "^4.1.5", - "typescript": "^5.6.2" + "cpy-cli": "^5.0.0" } } diff --git a/packages/plugin-runtime/src/PluginHandle.ts b/packages/plugin-runtime/src/PluginHandle.ts index 18dbbdb8f..25adcfc3d 100644 --- a/packages/plugin-runtime/src/PluginHandle.ts +++ b/packages/plugin-runtime/src/PluginHandle.ts @@ -15,7 +15,6 @@ export class PluginHandle { bootRequest: this.bootRequest, }; this.#instance = new PluginInstance(workerData, pluginToAppEvents); - console.log('Created plugin worker for ', this.bootRequest.dir); } sendToWorker(event: InternalEvent) { diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 99aa01126..1c5289a67 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -543,6 +543,15 @@ dependencies = [ "objc2 0.5.2", ] +[[package]] +name = "block2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d59b4c170e16f0405a2e95aff44432a0d41aa97675f3d52623effe95792a037" +dependencies = [ + "objc2 0.6.0", +] + [[package]] name = "blocking" version = "1.6.1" @@ -737,9 +746,9 @@ dependencies = [ [[package]] name = "cargo_toml" -version = "0.21.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fbd1fe9db3ebf71b89060adaf7b0504c2d6a425cf061313099547e382c2e472" +checksum = "02260d489095346e5cafd04dea8e8cb54d1d74fcd759022a9b72986ebe9a1257" dependencies = [ "serde", "toml", @@ -825,22 +834,6 @@ dependencies = [ "error-code", ] -[[package]] -name = "cocoa" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation 0.1.2", - "core-foundation 0.9.4", - "core-graphics 0.23.2", - "foreign-types 0.5.0", - "libc", - "objc", -] - [[package]] name = "cocoa" version = "0.26.0" @@ -849,7 +842,7 @@ checksum = "f79398230a6e2c08f5c9760610eb6924b52aa9e7950a619602baba59dcbbdbb2" dependencies = [ "bitflags 2.6.0", "block", - "cocoa-foundation 0.2.0", + "cocoa-foundation", "core-foundation 0.10.0", "core-graphics 0.24.0", "foreign-types 0.5.0", @@ -857,20 +850,6 @@ dependencies = [ "objc", ] -[[package]] -name = "cocoa-foundation" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", - "libc", - "objc", -] - [[package]] name = "cocoa-foundation" version = "0.2.0" @@ -1252,34 +1231,13 @@ dependencies = [ "subtle", ] -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys 0.4.1", -] - [[package]] name = "dirs" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ - "dirs-sys 0.5.0", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users 0.4.5", - "windows-sys 0.48.0", + "dirs-sys", ] [[package]] @@ -1290,7 +1248,7 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", - "redox_users 0.5.0", + "redox_users", "windows-sys 0.59.0", ] @@ -2436,9 +2394,9 @@ dependencies = [ [[package]] name = "ico" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3804960be0bb5e4edb1e1ad67afd321a9ecfd875c3e65c099468fd2717d7cae" +checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" dependencies = [ "byteorder", "png", @@ -3031,21 +2989,22 @@ dependencies = [ [[package]] name = "muda" -version = "0.15.1" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8123dfd4996055ac9b15a60ad263b44b01e539007523ad7a4a533a3d93b0591" +checksum = "4de14a9b5d569ca68d7c891d613b390cf5ab4f851c77aaa2f9e435555d3d9492" dependencies = [ "crossbeam-channel", "dpi", "gtk", "keyboard-types", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-core-foundation", + "objc2-foundation 0.3.0", "once_cell", "png", "serde", - "thiserror 1.0.63", + "thiserror 2.0.11", "windows-sys 0.59.0", ] @@ -3289,9 +3248,6 @@ name = "objc-sys" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" -dependencies = [ - "cc", -] [[package]] name = "objc2" @@ -3310,6 +3266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3531f65190d9cff863b77a99857e74c314dd16bf56c538c4b57c7cbc3f3a6e59" dependencies = [ "objc2-encode", + "objc2-exception-helper", ] [[package]] @@ -3322,10 +3279,10 @@ dependencies = [ "block2 0.5.1", "libc", "objc2 0.5.2", - "objc2-core-data", - "objc2-core-image", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", "objc2-foundation 0.2.2", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", ] [[package]] @@ -3335,29 +3292,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5906f93257178e2f7ae069efb89fbd6ee94f0592740b5f8a1512ca498814d0fb" dependencies = [ "bitflags 2.6.0", + "block2 0.6.0", + "libc", "objc2 0.6.0", + "objc2-cloud-kit", + "objc2-core-data 0.3.0", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image 0.3.0", "objc2-foundation 0.3.0", + "objc2-quartz-core 0.3.0", ] [[package]] name = "objc2-cloud-kit" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +checksum = "6c1948a9be5f469deadbd6bcb86ad7ff9e47b4f632380139722f7d9840c0d42c" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-core-location", - "objc2-foundation 0.2.2", + "objc2 0.6.0", + "objc2-foundation 0.3.0", ] [[package]] -name = "objc2-contacts" +name = "objc2-core-data" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ + "bitflags 2.6.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -3365,14 +3329,13 @@ dependencies = [ [[package]] name = "objc2-core-data" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +checksum = "1f860f8e841f6d32f754836f51e6bc7777cd7e7053cf18528233f6811d3eceb4" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", + "objc2 0.6.0", + "objc2-foundation 0.3.0", ] [[package]] @@ -3385,6 +3348,18 @@ dependencies = [ "objc2 0.6.0", ] +[[package]] +name = "objc2-core-graphics" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dca602628b65356b6513290a21a6405b4d4027b8b250f0b98dddbb28b7de02" +dependencies = [ + "bitflags 2.6.0", + "objc2 0.6.0", + "objc2-core-foundation", + "objc2-io-surface", +] + [[package]] name = "objc2-core-image" version = "0.2.2" @@ -3398,15 +3373,13 @@ dependencies = [ ] [[package]] -name = "objc2-core-location" -version = "0.2.2" +name = "objc2-core-image" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +checksum = "6ffa6bea72bf42c78b0b34e89c0bafac877d5f80bf91e159a5d96ea7f693ca56" dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", - "objc2-contacts", - "objc2-foundation 0.2.2", + "objc2 0.6.0", + "objc2-foundation 0.3.0", ] [[package]] @@ -3415,6 +3388,15 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" +[[package]] +name = "objc2-exception-helper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" +dependencies = [ + "cc", +] + [[package]] name = "objc2-foundation" version = "0.2.2" @@ -3435,20 +3417,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a21c6c9014b82c39515db5b396f91645182611c97d24637cf56ac01e5f8d998" dependencies = [ "bitflags 2.6.0", + "block2 0.6.0", + "libc", "objc2 0.6.0", "objc2-core-foundation", ] [[package]] -name = "objc2-link-presentation" -version = "0.2.2" +name = "objc2-io-surface" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +checksum = "161a8b87e32610086e1a7a9e9ec39f84459db7b3a0881c1f16ca5a2605581c19" dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", + "bitflags 2.6.0", + "objc2 0.6.0", + "objc2-core-foundation", ] [[package]] @@ -3489,71 +3472,40 @@ dependencies = [ ] [[package]] -name = "objc2-symbols" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" -dependencies = [ - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-ui-kit" -version = "0.2.2" +name = "objc2-quartz-core" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +checksum = "6fb3794501bb1bee12f08dcad8c61f2a5875791ad1c6f47faa71a0f033f20071" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-image", - "objc2-core-location", - "objc2-foundation 0.2.2", - "objc2-link-presentation", - "objc2-quartz-core", - "objc2-symbols", - "objc2-uniform-type-identifiers", - "objc2-user-notifications", -] - -[[package]] -name = "objc2-uniform-type-identifiers" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", + "objc2 0.6.0", + "objc2-foundation 0.3.0", ] [[package]] -name = "objc2-user-notifications" -version = "0.2.2" +name = "objc2-ui-kit" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +checksum = "777a571be14a42a3990d4ebedaeb8b54cd17377ec21b92e8200ac03797b3bee1" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-core-location", - "objc2-foundation 0.2.2", + "objc2 0.6.0", + "objc2-core-foundation", + "objc2-foundation 0.3.0", ] [[package]] name = "objc2-web-kit" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68bc69301064cebefc6c4c90ce9cba69225239e4b8ff99d445a2b5563797da65" +checksum = "b717127e4014b0f9f3e8bba3d3f2acec81f1bde01f656823036e823ed2c94dce" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", + "block2 0.6.0", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-core-foundation", + "objc2-foundation 0.3.0", ] [[package]] @@ -3567,9 +3519,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "open" @@ -4459,17 +4411,6 @@ dependencies = [ "bitflags 2.6.0", ] -[[package]] -name = "redox_users" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" -dependencies = [ - "getrandom 0.2.15", - "libredox", - "thiserror 1.0.63", -] - [[package]] name = "redox_users" version = "0.5.0" @@ -4483,9 +4424,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -5291,7 +5232,7 @@ dependencies = [ "objc2 0.5.2", "objc2-app-kit 0.2.2", "objc2-foundation 0.2.2", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", "raw-window-handle", "redox_syscall 0.5.3", "wasm-bindgen", @@ -5708,12 +5649,11 @@ dependencies = [ [[package]] name = "tao" -version = "0.31.1" +version = "0.32.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3731d04d4ac210cd5f344087733943b9bfb1a32654387dad4d1c70de21aee2c9" +checksum = "63c8b1020610b9138dd7b1e06cf259ae91aa05c30f3bd0d6b42a03997b92dec1" dependencies = [ "bitflags 2.6.0", - "cocoa 0.26.0", "core-foundation 0.10.0", "core-graphics 0.24.0", "crossbeam-channel", @@ -5730,7 +5670,9 @@ dependencies = [ "ndk", "ndk-context", "ndk-sys", - "objc", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-foundation 0.3.0", "once_cell", "parking_lot", "raw-window-handle", @@ -5738,8 +5680,8 @@ dependencies = [ "tao-macros", "unicode-segmentation", "url", - "windows 0.58.0", - "windows-core 0.58.0", + "windows", + "windows-core 0.60.1", "windows-version", "x11-dl", ] @@ -5780,13 +5722,13 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.2.5" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58a998b6be84104ca05c7e9a21f2180ddec020c8b84ea59a8fc8530a2a19588d" +checksum = "511dd38065a5d3b36c33cdba4362b99a40a5103bebcd4aebb930717e7c8ba292" dependencies = [ "anyhow", "bytes", - "dirs 6.0.0", + "dirs", "dunce", "embed_plist", "futures-util", @@ -5801,9 +5743,9 @@ dependencies = [ "log", "mime", "muda", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-foundation 0.3.0", "percent-encoding", "plist", "raw-window-handle", @@ -5826,18 +5768,18 @@ dependencies = [ "webkit2gtk", "webview2-com", "window-vibrancy", - "windows 0.58.0", + "windows", ] [[package]] name = "tauri-build" -version = "2.0.6" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51a2e96f3c0baa0581656bb58e6fdd0f7c9c31eaf6721a0c08689d938fe85f2d" +checksum = "7ffa8732a66f90903f5a585215f3cf1e87988d0359bc88c18a502efe7572c1de" dependencies = [ "anyhow", "cargo_toml", - "dirs 6.0.0", + "dirs", "glob", "heck 0.5.0", "json-patch", @@ -5853,9 +5795,9 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f77894f9ddb5cb6c04fcfe8c8869ebe0aded4dabf19917118d48be4a95599ab5" +checksum = "c266a247f14d63f40c6282c2653a8bac5cc3d482ca562a003a88513653ea817a" dependencies = [ "base64 0.22.1", "brotli 7.0.0", @@ -5880,9 +5822,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3240a5caed760a532e8f687be6f05b2c7d11a1d791fb53ccc08cfeb3e5308736" +checksum = "f47a1cf94b3bd6c4dc37dce1a43fc96120ff29a91757f0ab3cf713c7ad846e7c" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -5894,9 +5836,9 @@ dependencies = [ [[package]] name = "tauri-plugin" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5841b9a0200e954ef7457f8d327091424328891e267a97b641dc246cc54d0dec" +checksum = "9972871fcbddf16618f70412d965d4d845cd4b76d03fff168709961ef71e5cdf" dependencies = [ "anyhow", "glob", @@ -6005,7 +5947,7 @@ dependencies = [ "tauri-plugin", "thiserror 2.0.11", "url", - "windows 0.60.0", + "windows", "zbus 5.3.0", ] @@ -6070,7 +6012,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a31bfcfb4a8318008d2108ccfba439d8263cf48867baabf372cb0e9f24771896" dependencies = [ "base64 0.22.1", - "dirs 6.0.0", + "dirs", "flate2", "futures-util", "http", @@ -6112,10 +6054,11 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2274ef891ccc0a8d318deffa9d70053f947664d12d58b9c0d1ae5e89237e01f7" +checksum = "9e9c7bce5153f1ca7bc45eba37349b31ba50e975e28edc8b5766c5ec02b0b63a" dependencies = [ + "cookie", "dpi", "gtk", "http", @@ -6126,22 +6069,23 @@ dependencies = [ "tauri-utils", "thiserror 2.0.11", "url", - "windows 0.58.0", + "windows", ] [[package]] name = "tauri-runtime-wry" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3707b40711d3b9f6519150869e358ffbde7c57567fb9b5a8b51150606939b2a0" +checksum = "087188020fd6facb8578fe9b38e81fa0fe5fb85744c73da51a299f94a530a1e3" dependencies = [ "gtk", "http", "jni", "log", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-foundation 0.3.0", + "once_cell", "percent-encoding", "raw-window-handle", "softbuffer", @@ -6151,16 +6095,17 @@ dependencies = [ "url", "webkit2gtk", "webview2-com", - "windows 0.58.0", + "windows", "wry", ] [[package]] name = "tauri-utils" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "107a959dbd5ff53d89a98f6f2e3e987c611334141a43630caae1d80e79446dd6" +checksum = "82dcced4014e59af9790cc22f5d271df3be09ecd6728ec68861642553c8d01b7" dependencies = [ + "anyhow", "brotli 7.0.0", "cargo_metadata", "ctor", @@ -6610,22 +6555,23 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533fc2d4105e0e3d96ce1c71f2d308c9fbbe2ef9c587cab63dd627ab5bde218f" +checksum = "d433764348e7084bad2c5ea22c96c71b61b17afe3a11645710f533bd72b6a2b5" dependencies = [ - "core-graphics 0.24.0", "crossbeam-channel", - "dirs 5.0.1", + "dirs", "libappindicator", "muda", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.0", "once_cell", "png", "serde", - "thiserror 1.0.63", + "thiserror 2.0.11", "windows-sys 0.59.0", ] @@ -7198,16 +7144,16 @@ dependencies = [ [[package]] name = "webview2-com" -version = "0.34.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "823e7ebcfaea51e78f72c87fc3b65a1e602c321f407a0b36dbb327d7bb7cd921" +checksum = "b0d606f600e5272b514dbb66539dd068211cc20155be8d3958201b4b5bd79ed3" dependencies = [ "webview2-com-macros", "webview2-com-sys", - "windows 0.58.0", - "windows-core 0.58.0", - "windows-implement 0.58.0", - "windows-interface 0.58.0", + "windows", + "windows-core 0.60.1", + "windows-implement", + "windows-interface", ] [[package]] @@ -7223,13 +7169,13 @@ dependencies = [ [[package]] name = "webview2-com-sys" -version = "0.34.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a82bce72db6e5ee83c68b5de1e2cd6ea195b9fbff91cb37df5884cbe3222df4" +checksum = "bfb27fccd3c27f68e9a6af1bcf48c2d82534b8675b83608a4d81446d095a17ac" dependencies = [ - "thiserror 1.0.63", - "windows 0.58.0", - "windows-core 0.58.0", + "thiserror 2.0.11", + "windows", + "windows-core 0.60.1", ] [[package]] @@ -7281,27 +7227,19 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window-vibrancy" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33082acd404763b315866e14a0d5193f3422c81086657583937a750cdd3ec340" +checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" dependencies = [ - "cocoa 0.25.0", - "objc", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-core-foundation", + "objc2-foundation 0.3.0", "raw-window-handle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", "windows-version", ] -[[package]] -name = "windows" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows" version = "0.60.0" @@ -7333,27 +7271,14 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-core" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" -dependencies = [ - "windows-implement 0.58.0", - "windows-interface 0.58.0", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows-core" version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247" dependencies = [ - "windows-implement 0.59.0", - "windows-interface 0.59.1", + "windows-implement", + "windows-interface", "windows-link", "windows-result 0.3.2", "windows-strings 0.3.1", @@ -7369,17 +7294,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-implement" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "windows-implement" version = "0.59.0" @@ -7391,17 +7305,6 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "windows-interface" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "windows-interface" version = "0.59.1" @@ -7759,12 +7662,12 @@ dependencies = [ [[package]] name = "wry" -version = "0.48.0" +version = "0.50.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e644bf458e27b11b0ecafc9e5633d1304fdae82baca1d42185669752fe6ca4f" +checksum = "b19b78efae8b853c6c817e8752fc1dbf9cab8a8ffe9c30f399bd750ccf0f0730" dependencies = [ "base64 0.22.1", - "block2 0.5.1", + "block2 0.6.0", "cookie", "crossbeam-channel", "dpi", @@ -7778,9 +7681,10 @@ dependencies = [ "kuchikiki", "libc", "ndk", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-core-foundation", + "objc2-foundation 0.3.0", "objc2-ui-kit", "objc2-web-kit", "once_cell", @@ -7794,8 +7698,8 @@ dependencies = [ "webkit2gtk", "webkit2gtk-sys", "webview2-com", - "windows 0.58.0", - "windows-core 0.58.0", + "windows", + "windows-core 0.60.1", "windows-version", "x11-dl", ] @@ -7873,7 +7777,7 @@ name = "yaak-app" version = "0.0.0" dependencies = [ "chrono", - "cocoa 0.26.0", + "cocoa", "encoding_rs", "eventsource-client", "hex_color", @@ -8006,7 +7910,9 @@ dependencies = [ "serde_json", "sqlx", "tauri", + "tauri-plugin", "thiserror 2.0.11", + "tokio", "ts-rs", ] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index bfac4cb0b..7ebea8c7c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -31,7 +31,7 @@ strip = true # Automatically strip symbols from the binary. cargo-clippy = [] [build-dependencies] -tauri-build = { version = "2.0.6", features = [] } +tauri-build = { version = "2.1.0", features = [] } [target.'cfg(target_os = "macos")'.dependencies] objc = "0.2.7" @@ -87,8 +87,8 @@ yaak-ws = { path = "yaak-ws" } reqwest = "0.12.12" serde = "1.0.215" serde_json = "1.0.132" -tauri = "2.2.5" -tauri-plugin = "2.0.4" +tauri = "2.4.0" +tauri-plugin = "2.1.0" tauri-plugin-shell = "2.2.0" thiserror = "2.0.3" ts-rs = "10.0.0" diff --git a/src-tauri/gen/schemas/acl-manifests.json b/src-tauri/gen/schemas/acl-manifests.json index 26c087fa2..3895fc2b8 100644 --- a/src-tauri/gen/schemas/acl-manifests.json +++ b/src-tauri/gen/schemas/acl-manifests.json @@ -1 +1 @@ -{"clipboard-manager":{"default_permission":{"identifier":"default","description":"No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n","permissions":[]},"permissions":{"allow-clear":{"identifier":"allow-clear","description":"Enables the clear command without any pre-configured scope.","commands":{"allow":["clear"],"deny":[]}},"allow-read-image":{"identifier":"allow-read-image","description":"Enables the read_image command without any pre-configured scope.","commands":{"allow":["read_image"],"deny":[]}},"allow-read-text":{"identifier":"allow-read-text","description":"Enables the read_text command without any pre-configured scope.","commands":{"allow":["read_text"],"deny":[]}},"allow-write-html":{"identifier":"allow-write-html","description":"Enables the write_html command without any pre-configured scope.","commands":{"allow":["write_html"],"deny":[]}},"allow-write-image":{"identifier":"allow-write-image","description":"Enables the write_image command without any pre-configured scope.","commands":{"allow":["write_image"],"deny":[]}},"allow-write-text":{"identifier":"allow-write-text","description":"Enables the write_text command without any pre-configured scope.","commands":{"allow":["write_text"],"deny":[]}},"deny-clear":{"identifier":"deny-clear","description":"Denies the clear command without any pre-configured scope.","commands":{"allow":[],"deny":["clear"]}},"deny-read-image":{"identifier":"deny-read-image","description":"Denies the read_image command without any pre-configured scope.","commands":{"allow":[],"deny":["read_image"]}},"deny-read-text":{"identifier":"deny-read-text","description":"Denies the read_text command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text"]}},"deny-write-html":{"identifier":"deny-write-html","description":"Denies the write_html command without any pre-configured scope.","commands":{"allow":[],"deny":["write_html"]}},"deny-write-image":{"identifier":"deny-write-image","description":"Denies the write_image command without any pre-configured scope.","commands":{"allow":[],"deny":["write_image"]}},"deny-write-text":{"identifier":"deny-write-text","description":"Denies the write_text command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text"]}}},"permission_sets":{},"global_scope_schema":null},"core":{"default_permission":{"identifier":"default","description":"Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-ask","allow-confirm","allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope.","commands":{"allow":["ask"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope.","commands":{"allow":["confirm"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope.","commands":{"allow":[],"deny":["ask"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope.","commands":{"allow":[],"deny":["confirm"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"fs":{"default_permission":{"identifier":"default","description":"This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n","permissions":["create-app-specific-dirs","read-app-specific-dirs-recursive","deny-default"]},"permissions":{"allow-copy-file":{"identifier":"allow-copy-file","description":"Enables the copy_file command without any pre-configured scope.","commands":{"allow":["copy_file"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-exists":{"identifier":"allow-exists","description":"Enables the exists command without any pre-configured scope.","commands":{"allow":["exists"],"deny":[]}},"allow-fstat":{"identifier":"allow-fstat","description":"Enables the fstat command without any pre-configured scope.","commands":{"allow":["fstat"],"deny":[]}},"allow-ftruncate":{"identifier":"allow-ftruncate","description":"Enables the ftruncate command without any pre-configured scope.","commands":{"allow":["ftruncate"],"deny":[]}},"allow-lstat":{"identifier":"allow-lstat","description":"Enables the lstat command without any pre-configured scope.","commands":{"allow":["lstat"],"deny":[]}},"allow-mkdir":{"identifier":"allow-mkdir","description":"Enables the mkdir command without any pre-configured scope.","commands":{"allow":["mkdir"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-read":{"identifier":"allow-read","description":"Enables the read command without any pre-configured scope.","commands":{"allow":["read"],"deny":[]}},"allow-read-dir":{"identifier":"allow-read-dir","description":"Enables the read_dir command without any pre-configured scope.","commands":{"allow":["read_dir"],"deny":[]}},"allow-read-file":{"identifier":"allow-read-file","description":"Enables the read_file command without any pre-configured scope.","commands":{"allow":["read_file"],"deny":[]}},"allow-read-text-file":{"identifier":"allow-read-text-file","description":"Enables the read_text_file command without any pre-configured scope.","commands":{"allow":["read_text_file"],"deny":[]}},"allow-read-text-file-lines":{"identifier":"allow-read-text-file-lines","description":"Enables the read_text_file_lines command without any pre-configured scope.","commands":{"allow":["read_text_file_lines","read_text_file_lines_next"],"deny":[]}},"allow-read-text-file-lines-next":{"identifier":"allow-read-text-file-lines-next","description":"Enables the read_text_file_lines_next command without any pre-configured scope.","commands":{"allow":["read_text_file_lines_next"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-rename":{"identifier":"allow-rename","description":"Enables the rename command without any pre-configured scope.","commands":{"allow":["rename"],"deny":[]}},"allow-seek":{"identifier":"allow-seek","description":"Enables the seek command without any pre-configured scope.","commands":{"allow":["seek"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"allow-stat":{"identifier":"allow-stat","description":"Enables the stat command without any pre-configured scope.","commands":{"allow":["stat"],"deny":[]}},"allow-truncate":{"identifier":"allow-truncate","description":"Enables the truncate command without any pre-configured scope.","commands":{"allow":["truncate"],"deny":[]}},"allow-unwatch":{"identifier":"allow-unwatch","description":"Enables the unwatch command without any pre-configured scope.","commands":{"allow":["unwatch"],"deny":[]}},"allow-watch":{"identifier":"allow-watch","description":"Enables the watch command without any pre-configured scope.","commands":{"allow":["watch"],"deny":[]}},"allow-write":{"identifier":"allow-write","description":"Enables the write command without any pre-configured scope.","commands":{"allow":["write"],"deny":[]}},"allow-write-file":{"identifier":"allow-write-file","description":"Enables the write_file command without any pre-configured scope.","commands":{"allow":["write_file","open","write"],"deny":[]}},"allow-write-text-file":{"identifier":"allow-write-text-file","description":"Enables the write_text_file command without any pre-configured scope.","commands":{"allow":["write_text_file"],"deny":[]}},"create-app-specific-dirs":{"identifier":"create-app-specific-dirs","description":"This permissions allows to create the application specific directories.\n","commands":{"allow":["mkdir","scope-app-index"],"deny":[]}},"deny-copy-file":{"identifier":"deny-copy-file","description":"Denies the copy_file command without any pre-configured scope.","commands":{"allow":[],"deny":["copy_file"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-exists":{"identifier":"deny-exists","description":"Denies the exists command without any pre-configured scope.","commands":{"allow":[],"deny":["exists"]}},"deny-fstat":{"identifier":"deny-fstat","description":"Denies the fstat command without any pre-configured scope.","commands":{"allow":[],"deny":["fstat"]}},"deny-ftruncate":{"identifier":"deny-ftruncate","description":"Denies the ftruncate command without any pre-configured scope.","commands":{"allow":[],"deny":["ftruncate"]}},"deny-lstat":{"identifier":"deny-lstat","description":"Denies the lstat command without any pre-configured scope.","commands":{"allow":[],"deny":["lstat"]}},"deny-mkdir":{"identifier":"deny-mkdir","description":"Denies the mkdir command without any pre-configured scope.","commands":{"allow":[],"deny":["mkdir"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-read":{"identifier":"deny-read","description":"Denies the read command without any pre-configured scope.","commands":{"allow":[],"deny":["read"]}},"deny-read-dir":{"identifier":"deny-read-dir","description":"Denies the read_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["read_dir"]}},"deny-read-file":{"identifier":"deny-read-file","description":"Denies the read_file command without any pre-configured scope.","commands":{"allow":[],"deny":["read_file"]}},"deny-read-text-file":{"identifier":"deny-read-text-file","description":"Denies the read_text_file command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file"]}},"deny-read-text-file-lines":{"identifier":"deny-read-text-file-lines","description":"Denies the read_text_file_lines command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file_lines"]}},"deny-read-text-file-lines-next":{"identifier":"deny-read-text-file-lines-next","description":"Denies the read_text_file_lines_next command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file_lines_next"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-rename":{"identifier":"deny-rename","description":"Denies the rename command without any pre-configured scope.","commands":{"allow":[],"deny":["rename"]}},"deny-seek":{"identifier":"deny-seek","description":"Denies the seek command without any pre-configured scope.","commands":{"allow":[],"deny":["seek"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}},"deny-stat":{"identifier":"deny-stat","description":"Denies the stat command without any pre-configured scope.","commands":{"allow":[],"deny":["stat"]}},"deny-truncate":{"identifier":"deny-truncate","description":"Denies the truncate command without any pre-configured scope.","commands":{"allow":[],"deny":["truncate"]}},"deny-unwatch":{"identifier":"deny-unwatch","description":"Denies the unwatch command without any pre-configured scope.","commands":{"allow":[],"deny":["unwatch"]}},"deny-watch":{"identifier":"deny-watch","description":"Denies the watch command without any pre-configured scope.","commands":{"allow":[],"deny":["watch"]}},"deny-webview-data-linux":{"identifier":"deny-webview-data-linux","description":"This denies read access to the\n`$APPLOCALDATA` folder on linux as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.","commands":{"allow":[],"deny":[]}},"deny-webview-data-windows":{"identifier":"deny-webview-data-windows","description":"This denies read access to the\n`$APPLOCALDATA/EBWebView` folder on windows as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.","commands":{"allow":[],"deny":[]}},"deny-write":{"identifier":"deny-write","description":"Denies the write command without any pre-configured scope.","commands":{"allow":[],"deny":["write"]}},"deny-write-file":{"identifier":"deny-write-file","description":"Denies the write_file command without any pre-configured scope.","commands":{"allow":[],"deny":["write_file"]}},"deny-write-text-file":{"identifier":"deny-write-text-file","description":"Denies the write_text_file command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text_file"]}},"read-all":{"identifier":"read-all","description":"This enables all read related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","read_file","read","open","read_text_file","read_text_file_lines","read_text_file_lines_next","seek","stat","lstat","fstat","exists","watch","unwatch"],"deny":[]}},"read-app-specific-dirs-recursive":{"identifier":"read-app-specific-dirs-recursive","description":"This permission allows recursive read functionality on the application\nspecific base directories. \n","commands":{"allow":["read_dir","read_file","read_text_file","read_text_file_lines","read_text_file_lines_next","exists","scope-app-recursive"],"deny":[]}},"read-dirs":{"identifier":"read-dirs","description":"This enables directory read and file metadata related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","stat","lstat","fstat","exists"],"deny":[]}},"read-files":{"identifier":"read-files","description":"This enables file read related commands without any pre-configured accessible paths.","commands":{"allow":["read_file","read","open","read_text_file","read_text_file_lines","read_text_file_lines_next","seek","stat","lstat","fstat","exists"],"deny":[]}},"read-meta":{"identifier":"read-meta","description":"This enables all index or metadata related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","stat","lstat","fstat","exists","size"],"deny":[]}},"scope":{"identifier":"scope","description":"An empty permission you can use to modify the global scope.","commands":{"allow":[],"deny":[]}},"scope-app":{"identifier":"scope-app","description":"This scope permits access to all files and list content of top level directories in the application folders.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/*"},{"path":"$APPDATA"},{"path":"$APPDATA/*"},{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/*"},{"path":"$APPCACHE"},{"path":"$APPCACHE/*"},{"path":"$APPLOG"},{"path":"$APPLOG/*"}]}},"scope-app-index":{"identifier":"scope-app-index","description":"This scope permits to list all files and folders in the application directories.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPDATA"},{"path":"$APPLOCALDATA"},{"path":"$APPCACHE"},{"path":"$APPLOG"}]}},"scope-app-recursive":{"identifier":"scope-app-recursive","description":"This scope permits recursive access to the complete application folders, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/**"},{"path":"$APPDATA"},{"path":"$APPDATA/**"},{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/**"},{"path":"$APPCACHE"},{"path":"$APPCACHE/**"},{"path":"$APPLOG"},{"path":"$APPLOG/**"}]}},"scope-appcache":{"identifier":"scope-appcache","description":"This scope permits access to all files and list content of top level directories in the `$APPCACHE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"},{"path":"$APPCACHE/*"}]}},"scope-appcache-index":{"identifier":"scope-appcache-index","description":"This scope permits to list all files and folders in the `$APPCACHE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"}]}},"scope-appcache-recursive":{"identifier":"scope-appcache-recursive","description":"This scope permits recursive access to the complete `$APPCACHE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"},{"path":"$APPCACHE/**"}]}},"scope-appconfig":{"identifier":"scope-appconfig","description":"This scope permits access to all files and list content of top level directories in the `$APPCONFIG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/*"}]}},"scope-appconfig-index":{"identifier":"scope-appconfig-index","description":"This scope permits to list all files and folders in the `$APPCONFIG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"}]}},"scope-appconfig-recursive":{"identifier":"scope-appconfig-recursive","description":"This scope permits recursive access to the complete `$APPCONFIG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/**"}]}},"scope-appdata":{"identifier":"scope-appdata","description":"This scope permits access to all files and list content of top level directories in the `$APPDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"},{"path":"$APPDATA/*"}]}},"scope-appdata-index":{"identifier":"scope-appdata-index","description":"This scope permits to list all files and folders in the `$APPDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"}]}},"scope-appdata-recursive":{"identifier":"scope-appdata-recursive","description":"This scope permits recursive access to the complete `$APPDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]}},"scope-applocaldata":{"identifier":"scope-applocaldata","description":"This scope permits access to all files and list content of top level directories in the `$APPLOCALDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/*"}]}},"scope-applocaldata-index":{"identifier":"scope-applocaldata-index","description":"This scope permits to list all files and folders in the `$APPLOCALDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"}]}},"scope-applocaldata-recursive":{"identifier":"scope-applocaldata-recursive","description":"This scope permits recursive access to the complete `$APPLOCALDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/**"}]}},"scope-applog":{"identifier":"scope-applog","description":"This scope permits access to all files and list content of top level directories in the `$APPLOG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"},{"path":"$APPLOG/*"}]}},"scope-applog-index":{"identifier":"scope-applog-index","description":"This scope permits to list all files and folders in the `$APPLOG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"}]}},"scope-applog-recursive":{"identifier":"scope-applog-recursive","description":"This scope permits recursive access to the complete `$APPLOG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"},{"path":"$APPLOG/**"}]}},"scope-audio":{"identifier":"scope-audio","description":"This scope permits access to all files and list content of top level directories in the `$AUDIO` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"},{"path":"$AUDIO/*"}]}},"scope-audio-index":{"identifier":"scope-audio-index","description":"This scope permits to list all files and folders in the `$AUDIO`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"}]}},"scope-audio-recursive":{"identifier":"scope-audio-recursive","description":"This scope permits recursive access to the complete `$AUDIO` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"},{"path":"$AUDIO/**"}]}},"scope-cache":{"identifier":"scope-cache","description":"This scope permits access to all files and list content of top level directories in the `$CACHE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"},{"path":"$CACHE/*"}]}},"scope-cache-index":{"identifier":"scope-cache-index","description":"This scope permits to list all files and folders in the `$CACHE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"}]}},"scope-cache-recursive":{"identifier":"scope-cache-recursive","description":"This scope permits recursive access to the complete `$CACHE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"},{"path":"$CACHE/**"}]}},"scope-config":{"identifier":"scope-config","description":"This scope permits access to all files and list content of top level directories in the `$CONFIG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"},{"path":"$CONFIG/*"}]}},"scope-config-index":{"identifier":"scope-config-index","description":"This scope permits to list all files and folders in the `$CONFIG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"}]}},"scope-config-recursive":{"identifier":"scope-config-recursive","description":"This scope permits recursive access to the complete `$CONFIG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"},{"path":"$CONFIG/**"}]}},"scope-data":{"identifier":"scope-data","description":"This scope permits access to all files and list content of top level directories in the `$DATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"},{"path":"$DATA/*"}]}},"scope-data-index":{"identifier":"scope-data-index","description":"This scope permits to list all files and folders in the `$DATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"}]}},"scope-data-recursive":{"identifier":"scope-data-recursive","description":"This scope permits recursive access to the complete `$DATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"},{"path":"$DATA/**"}]}},"scope-desktop":{"identifier":"scope-desktop","description":"This scope permits access to all files and list content of top level directories in the `$DESKTOP` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"},{"path":"$DESKTOP/*"}]}},"scope-desktop-index":{"identifier":"scope-desktop-index","description":"This scope permits to list all files and folders in the `$DESKTOP`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"}]}},"scope-desktop-recursive":{"identifier":"scope-desktop-recursive","description":"This scope permits recursive access to the complete `$DESKTOP` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"},{"path":"$DESKTOP/**"}]}},"scope-document":{"identifier":"scope-document","description":"This scope permits access to all files and list content of top level directories in the `$DOCUMENT` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"},{"path":"$DOCUMENT/*"}]}},"scope-document-index":{"identifier":"scope-document-index","description":"This scope permits to list all files and folders in the `$DOCUMENT`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"}]}},"scope-document-recursive":{"identifier":"scope-document-recursive","description":"This scope permits recursive access to the complete `$DOCUMENT` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"},{"path":"$DOCUMENT/**"}]}},"scope-download":{"identifier":"scope-download","description":"This scope permits access to all files and list content of top level directories in the `$DOWNLOAD` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"},{"path":"$DOWNLOAD/*"}]}},"scope-download-index":{"identifier":"scope-download-index","description":"This scope permits to list all files and folders in the `$DOWNLOAD`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"}]}},"scope-download-recursive":{"identifier":"scope-download-recursive","description":"This scope permits recursive access to the complete `$DOWNLOAD` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"},{"path":"$DOWNLOAD/**"}]}},"scope-exe":{"identifier":"scope-exe","description":"This scope permits access to all files and list content of top level directories in the `$EXE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"},{"path":"$EXE/*"}]}},"scope-exe-index":{"identifier":"scope-exe-index","description":"This scope permits to list all files and folders in the `$EXE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"}]}},"scope-exe-recursive":{"identifier":"scope-exe-recursive","description":"This scope permits recursive access to the complete `$EXE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"},{"path":"$EXE/**"}]}},"scope-font":{"identifier":"scope-font","description":"This scope permits access to all files and list content of top level directories in the `$FONT` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"},{"path":"$FONT/*"}]}},"scope-font-index":{"identifier":"scope-font-index","description":"This scope permits to list all files and folders in the `$FONT`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"}]}},"scope-font-recursive":{"identifier":"scope-font-recursive","description":"This scope permits recursive access to the complete `$FONT` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"},{"path":"$FONT/**"}]}},"scope-home":{"identifier":"scope-home","description":"This scope permits access to all files and list content of top level directories in the `$HOME` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"},{"path":"$HOME/*"}]}},"scope-home-index":{"identifier":"scope-home-index","description":"This scope permits to list all files and folders in the `$HOME`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"}]}},"scope-home-recursive":{"identifier":"scope-home-recursive","description":"This scope permits recursive access to the complete `$HOME` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"},{"path":"$HOME/**"}]}},"scope-localdata":{"identifier":"scope-localdata","description":"This scope permits access to all files and list content of top level directories in the `$LOCALDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"},{"path":"$LOCALDATA/*"}]}},"scope-localdata-index":{"identifier":"scope-localdata-index","description":"This scope permits to list all files and folders in the `$LOCALDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"}]}},"scope-localdata-recursive":{"identifier":"scope-localdata-recursive","description":"This scope permits recursive access to the complete `$LOCALDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"},{"path":"$LOCALDATA/**"}]}},"scope-log":{"identifier":"scope-log","description":"This scope permits access to all files and list content of top level directories in the `$LOG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"},{"path":"$LOG/*"}]}},"scope-log-index":{"identifier":"scope-log-index","description":"This scope permits to list all files and folders in the `$LOG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"}]}},"scope-log-recursive":{"identifier":"scope-log-recursive","description":"This scope permits recursive access to the complete `$LOG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"},{"path":"$LOG/**"}]}},"scope-picture":{"identifier":"scope-picture","description":"This scope permits access to all files and list content of top level directories in the `$PICTURE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"},{"path":"$PICTURE/*"}]}},"scope-picture-index":{"identifier":"scope-picture-index","description":"This scope permits to list all files and folders in the `$PICTURE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"}]}},"scope-picture-recursive":{"identifier":"scope-picture-recursive","description":"This scope permits recursive access to the complete `$PICTURE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"},{"path":"$PICTURE/**"}]}},"scope-public":{"identifier":"scope-public","description":"This scope permits access to all files and list content of top level directories in the `$PUBLIC` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"},{"path":"$PUBLIC/*"}]}},"scope-public-index":{"identifier":"scope-public-index","description":"This scope permits to list all files and folders in the `$PUBLIC`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"}]}},"scope-public-recursive":{"identifier":"scope-public-recursive","description":"This scope permits recursive access to the complete `$PUBLIC` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"},{"path":"$PUBLIC/**"}]}},"scope-resource":{"identifier":"scope-resource","description":"This scope permits access to all files and list content of top level directories in the `$RESOURCE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"},{"path":"$RESOURCE/*"}]}},"scope-resource-index":{"identifier":"scope-resource-index","description":"This scope permits to list all files and folders in the `$RESOURCE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"}]}},"scope-resource-recursive":{"identifier":"scope-resource-recursive","description":"This scope permits recursive access to the complete `$RESOURCE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"},{"path":"$RESOURCE/**"}]}},"scope-runtime":{"identifier":"scope-runtime","description":"This scope permits access to all files and list content of top level directories in the `$RUNTIME` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"},{"path":"$RUNTIME/*"}]}},"scope-runtime-index":{"identifier":"scope-runtime-index","description":"This scope permits to list all files and folders in the `$RUNTIME`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"}]}},"scope-runtime-recursive":{"identifier":"scope-runtime-recursive","description":"This scope permits recursive access to the complete `$RUNTIME` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"},{"path":"$RUNTIME/**"}]}},"scope-temp":{"identifier":"scope-temp","description":"This scope permits access to all files and list content of top level directories in the `$TEMP` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"},{"path":"$TEMP/*"}]}},"scope-temp-index":{"identifier":"scope-temp-index","description":"This scope permits to list all files and folders in the `$TEMP`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"}]}},"scope-temp-recursive":{"identifier":"scope-temp-recursive","description":"This scope permits recursive access to the complete `$TEMP` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"},{"path":"$TEMP/**"}]}},"scope-template":{"identifier":"scope-template","description":"This scope permits access to all files and list content of top level directories in the `$TEMPLATE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"},{"path":"$TEMPLATE/*"}]}},"scope-template-index":{"identifier":"scope-template-index","description":"This scope permits to list all files and folders in the `$TEMPLATE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"}]}},"scope-template-recursive":{"identifier":"scope-template-recursive","description":"This scope permits recursive access to the complete `$TEMPLATE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"},{"path":"$TEMPLATE/**"}]}},"scope-video":{"identifier":"scope-video","description":"This scope permits access to all files and list content of top level directories in the `$VIDEO` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"},{"path":"$VIDEO/*"}]}},"scope-video-index":{"identifier":"scope-video-index","description":"This scope permits to list all files and folders in the `$VIDEO`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"}]}},"scope-video-recursive":{"identifier":"scope-video-recursive","description":"This scope permits recursive access to the complete `$VIDEO` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"},{"path":"$VIDEO/**"}]}},"write-all":{"identifier":"write-all","description":"This enables all write related commands without any pre-configured accessible paths.","commands":{"allow":["mkdir","create","copy_file","remove","rename","truncate","ftruncate","write","write_file","write_text_file"],"deny":[]}},"write-files":{"identifier":"write-files","description":"This enables all file write related commands without any pre-configured accessible paths.","commands":{"allow":["create","copy_file","remove","rename","truncate","ftruncate","write","write_file","write_text_file"],"deny":[]}}},"permission_sets":{"allow-app-meta":{"identifier":"allow-app-meta","description":"This allows non-recursive read access to metadata of the application folders, including file listing and statistics.","permissions":["read-meta","scope-app-index"]},"allow-app-meta-recursive":{"identifier":"allow-app-meta-recursive","description":"This allows full recursive read access to metadata of the application folders, including file listing and statistics.","permissions":["read-meta","scope-app-recursive"]},"allow-app-read":{"identifier":"allow-app-read","description":"This allows non-recursive read access to the application folders.","permissions":["read-all","scope-app"]},"allow-app-read-recursive":{"identifier":"allow-app-read-recursive","description":"This allows full recursive read access to the complete application folders, files and subdirectories.","permissions":["read-all","scope-app-recursive"]},"allow-app-write":{"identifier":"allow-app-write","description":"This allows non-recursive write access to the application folders.","permissions":["write-all","scope-app"]},"allow-app-write-recursive":{"identifier":"allow-app-write-recursive","description":"This allows full recursive write access to the complete application folders, files and subdirectories.","permissions":["write-all","scope-app-recursive"]},"allow-appcache-meta":{"identifier":"allow-appcache-meta","description":"This allows non-recursive read access to metadata of the `$APPCACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-appcache-index"]},"allow-appcache-meta-recursive":{"identifier":"allow-appcache-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPCACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-appcache-recursive"]},"allow-appcache-read":{"identifier":"allow-appcache-read","description":"This allows non-recursive read access to the `$APPCACHE` folder.","permissions":["read-all","scope-appcache"]},"allow-appcache-read-recursive":{"identifier":"allow-appcache-read-recursive","description":"This allows full recursive read access to the complete `$APPCACHE` folder, files and subdirectories.","permissions":["read-all","scope-appcache-recursive"]},"allow-appcache-write":{"identifier":"allow-appcache-write","description":"This allows non-recursive write access to the `$APPCACHE` folder.","permissions":["write-all","scope-appcache"]},"allow-appcache-write-recursive":{"identifier":"allow-appcache-write-recursive","description":"This allows full recursive write access to the complete `$APPCACHE` folder, files and subdirectories.","permissions":["write-all","scope-appcache-recursive"]},"allow-appconfig-meta":{"identifier":"allow-appconfig-meta","description":"This allows non-recursive read access to metadata of the `$APPCONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-appconfig-index"]},"allow-appconfig-meta-recursive":{"identifier":"allow-appconfig-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPCONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-appconfig-recursive"]},"allow-appconfig-read":{"identifier":"allow-appconfig-read","description":"This allows non-recursive read access to the `$APPCONFIG` folder.","permissions":["read-all","scope-appconfig"]},"allow-appconfig-read-recursive":{"identifier":"allow-appconfig-read-recursive","description":"This allows full recursive read access to the complete `$APPCONFIG` folder, files and subdirectories.","permissions":["read-all","scope-appconfig-recursive"]},"allow-appconfig-write":{"identifier":"allow-appconfig-write","description":"This allows non-recursive write access to the `$APPCONFIG` folder.","permissions":["write-all","scope-appconfig"]},"allow-appconfig-write-recursive":{"identifier":"allow-appconfig-write-recursive","description":"This allows full recursive write access to the complete `$APPCONFIG` folder, files and subdirectories.","permissions":["write-all","scope-appconfig-recursive"]},"allow-appdata-meta":{"identifier":"allow-appdata-meta","description":"This allows non-recursive read access to metadata of the `$APPDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-appdata-index"]},"allow-appdata-meta-recursive":{"identifier":"allow-appdata-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-appdata-recursive"]},"allow-appdata-read":{"identifier":"allow-appdata-read","description":"This allows non-recursive read access to the `$APPDATA` folder.","permissions":["read-all","scope-appdata"]},"allow-appdata-read-recursive":{"identifier":"allow-appdata-read-recursive","description":"This allows full recursive read access to the complete `$APPDATA` folder, files and subdirectories.","permissions":["read-all","scope-appdata-recursive"]},"allow-appdata-write":{"identifier":"allow-appdata-write","description":"This allows non-recursive write access to the `$APPDATA` folder.","permissions":["write-all","scope-appdata"]},"allow-appdata-write-recursive":{"identifier":"allow-appdata-write-recursive","description":"This allows full recursive write access to the complete `$APPDATA` folder, files and subdirectories.","permissions":["write-all","scope-appdata-recursive"]},"allow-applocaldata-meta":{"identifier":"allow-applocaldata-meta","description":"This allows non-recursive read access to metadata of the `$APPLOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-applocaldata-index"]},"allow-applocaldata-meta-recursive":{"identifier":"allow-applocaldata-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPLOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-applocaldata-recursive"]},"allow-applocaldata-read":{"identifier":"allow-applocaldata-read","description":"This allows non-recursive read access to the `$APPLOCALDATA` folder.","permissions":["read-all","scope-applocaldata"]},"allow-applocaldata-read-recursive":{"identifier":"allow-applocaldata-read-recursive","description":"This allows full recursive read access to the complete `$APPLOCALDATA` folder, files and subdirectories.","permissions":["read-all","scope-applocaldata-recursive"]},"allow-applocaldata-write":{"identifier":"allow-applocaldata-write","description":"This allows non-recursive write access to the `$APPLOCALDATA` folder.","permissions":["write-all","scope-applocaldata"]},"allow-applocaldata-write-recursive":{"identifier":"allow-applocaldata-write-recursive","description":"This allows full recursive write access to the complete `$APPLOCALDATA` folder, files and subdirectories.","permissions":["write-all","scope-applocaldata-recursive"]},"allow-applog-meta":{"identifier":"allow-applog-meta","description":"This allows non-recursive read access to metadata of the `$APPLOG` folder, including file listing and statistics.","permissions":["read-meta","scope-applog-index"]},"allow-applog-meta-recursive":{"identifier":"allow-applog-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPLOG` folder, including file listing and statistics.","permissions":["read-meta","scope-applog-recursive"]},"allow-applog-read":{"identifier":"allow-applog-read","description":"This allows non-recursive read access to the `$APPLOG` folder.","permissions":["read-all","scope-applog"]},"allow-applog-read-recursive":{"identifier":"allow-applog-read-recursive","description":"This allows full recursive read access to the complete `$APPLOG` folder, files and subdirectories.","permissions":["read-all","scope-applog-recursive"]},"allow-applog-write":{"identifier":"allow-applog-write","description":"This allows non-recursive write access to the `$APPLOG` folder.","permissions":["write-all","scope-applog"]},"allow-applog-write-recursive":{"identifier":"allow-applog-write-recursive","description":"This allows full recursive write access to the complete `$APPLOG` folder, files and subdirectories.","permissions":["write-all","scope-applog-recursive"]},"allow-audio-meta":{"identifier":"allow-audio-meta","description":"This allows non-recursive read access to metadata of the `$AUDIO` folder, including file listing and statistics.","permissions":["read-meta","scope-audio-index"]},"allow-audio-meta-recursive":{"identifier":"allow-audio-meta-recursive","description":"This allows full recursive read access to metadata of the `$AUDIO` folder, including file listing and statistics.","permissions":["read-meta","scope-audio-recursive"]},"allow-audio-read":{"identifier":"allow-audio-read","description":"This allows non-recursive read access to the `$AUDIO` folder.","permissions":["read-all","scope-audio"]},"allow-audio-read-recursive":{"identifier":"allow-audio-read-recursive","description":"This allows full recursive read access to the complete `$AUDIO` folder, files and subdirectories.","permissions":["read-all","scope-audio-recursive"]},"allow-audio-write":{"identifier":"allow-audio-write","description":"This allows non-recursive write access to the `$AUDIO` folder.","permissions":["write-all","scope-audio"]},"allow-audio-write-recursive":{"identifier":"allow-audio-write-recursive","description":"This allows full recursive write access to the complete `$AUDIO` folder, files and subdirectories.","permissions":["write-all","scope-audio-recursive"]},"allow-cache-meta":{"identifier":"allow-cache-meta","description":"This allows non-recursive read access to metadata of the `$CACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-cache-index"]},"allow-cache-meta-recursive":{"identifier":"allow-cache-meta-recursive","description":"This allows full recursive read access to metadata of the `$CACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-cache-recursive"]},"allow-cache-read":{"identifier":"allow-cache-read","description":"This allows non-recursive read access to the `$CACHE` folder.","permissions":["read-all","scope-cache"]},"allow-cache-read-recursive":{"identifier":"allow-cache-read-recursive","description":"This allows full recursive read access to the complete `$CACHE` folder, files and subdirectories.","permissions":["read-all","scope-cache-recursive"]},"allow-cache-write":{"identifier":"allow-cache-write","description":"This allows non-recursive write access to the `$CACHE` folder.","permissions":["write-all","scope-cache"]},"allow-cache-write-recursive":{"identifier":"allow-cache-write-recursive","description":"This allows full recursive write access to the complete `$CACHE` folder, files and subdirectories.","permissions":["write-all","scope-cache-recursive"]},"allow-config-meta":{"identifier":"allow-config-meta","description":"This allows non-recursive read access to metadata of the `$CONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-config-index"]},"allow-config-meta-recursive":{"identifier":"allow-config-meta-recursive","description":"This allows full recursive read access to metadata of the `$CONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-config-recursive"]},"allow-config-read":{"identifier":"allow-config-read","description":"This allows non-recursive read access to the `$CONFIG` folder.","permissions":["read-all","scope-config"]},"allow-config-read-recursive":{"identifier":"allow-config-read-recursive","description":"This allows full recursive read access to the complete `$CONFIG` folder, files and subdirectories.","permissions":["read-all","scope-config-recursive"]},"allow-config-write":{"identifier":"allow-config-write","description":"This allows non-recursive write access to the `$CONFIG` folder.","permissions":["write-all","scope-config"]},"allow-config-write-recursive":{"identifier":"allow-config-write-recursive","description":"This allows full recursive write access to the complete `$CONFIG` folder, files and subdirectories.","permissions":["write-all","scope-config-recursive"]},"allow-data-meta":{"identifier":"allow-data-meta","description":"This allows non-recursive read access to metadata of the `$DATA` folder, including file listing and statistics.","permissions":["read-meta","scope-data-index"]},"allow-data-meta-recursive":{"identifier":"allow-data-meta-recursive","description":"This allows full recursive read access to metadata of the `$DATA` folder, including file listing and statistics.","permissions":["read-meta","scope-data-recursive"]},"allow-data-read":{"identifier":"allow-data-read","description":"This allows non-recursive read access to the `$DATA` folder.","permissions":["read-all","scope-data"]},"allow-data-read-recursive":{"identifier":"allow-data-read-recursive","description":"This allows full recursive read access to the complete `$DATA` folder, files and subdirectories.","permissions":["read-all","scope-data-recursive"]},"allow-data-write":{"identifier":"allow-data-write","description":"This allows non-recursive write access to the `$DATA` folder.","permissions":["write-all","scope-data"]},"allow-data-write-recursive":{"identifier":"allow-data-write-recursive","description":"This allows full recursive write access to the complete `$DATA` folder, files and subdirectories.","permissions":["write-all","scope-data-recursive"]},"allow-desktop-meta":{"identifier":"allow-desktop-meta","description":"This allows non-recursive read access to metadata of the `$DESKTOP` folder, including file listing and statistics.","permissions":["read-meta","scope-desktop-index"]},"allow-desktop-meta-recursive":{"identifier":"allow-desktop-meta-recursive","description":"This allows full recursive read access to metadata of the `$DESKTOP` folder, including file listing and statistics.","permissions":["read-meta","scope-desktop-recursive"]},"allow-desktop-read":{"identifier":"allow-desktop-read","description":"This allows non-recursive read access to the `$DESKTOP` folder.","permissions":["read-all","scope-desktop"]},"allow-desktop-read-recursive":{"identifier":"allow-desktop-read-recursive","description":"This allows full recursive read access to the complete `$DESKTOP` folder, files and subdirectories.","permissions":["read-all","scope-desktop-recursive"]},"allow-desktop-write":{"identifier":"allow-desktop-write","description":"This allows non-recursive write access to the `$DESKTOP` folder.","permissions":["write-all","scope-desktop"]},"allow-desktop-write-recursive":{"identifier":"allow-desktop-write-recursive","description":"This allows full recursive write access to the complete `$DESKTOP` folder, files and subdirectories.","permissions":["write-all","scope-desktop-recursive"]},"allow-document-meta":{"identifier":"allow-document-meta","description":"This allows non-recursive read access to metadata of the `$DOCUMENT` folder, including file listing and statistics.","permissions":["read-meta","scope-document-index"]},"allow-document-meta-recursive":{"identifier":"allow-document-meta-recursive","description":"This allows full recursive read access to metadata of the `$DOCUMENT` folder, including file listing and statistics.","permissions":["read-meta","scope-document-recursive"]},"allow-document-read":{"identifier":"allow-document-read","description":"This allows non-recursive read access to the `$DOCUMENT` folder.","permissions":["read-all","scope-document"]},"allow-document-read-recursive":{"identifier":"allow-document-read-recursive","description":"This allows full recursive read access to the complete `$DOCUMENT` folder, files and subdirectories.","permissions":["read-all","scope-document-recursive"]},"allow-document-write":{"identifier":"allow-document-write","description":"This allows non-recursive write access to the `$DOCUMENT` folder.","permissions":["write-all","scope-document"]},"allow-document-write-recursive":{"identifier":"allow-document-write-recursive","description":"This allows full recursive write access to the complete `$DOCUMENT` folder, files and subdirectories.","permissions":["write-all","scope-document-recursive"]},"allow-download-meta":{"identifier":"allow-download-meta","description":"This allows non-recursive read access to metadata of the `$DOWNLOAD` folder, including file listing and statistics.","permissions":["read-meta","scope-download-index"]},"allow-download-meta-recursive":{"identifier":"allow-download-meta-recursive","description":"This allows full recursive read access to metadata of the `$DOWNLOAD` folder, including file listing and statistics.","permissions":["read-meta","scope-download-recursive"]},"allow-download-read":{"identifier":"allow-download-read","description":"This allows non-recursive read access to the `$DOWNLOAD` folder.","permissions":["read-all","scope-download"]},"allow-download-read-recursive":{"identifier":"allow-download-read-recursive","description":"This allows full recursive read access to the complete `$DOWNLOAD` folder, files and subdirectories.","permissions":["read-all","scope-download-recursive"]},"allow-download-write":{"identifier":"allow-download-write","description":"This allows non-recursive write access to the `$DOWNLOAD` folder.","permissions":["write-all","scope-download"]},"allow-download-write-recursive":{"identifier":"allow-download-write-recursive","description":"This allows full recursive write access to the complete `$DOWNLOAD` folder, files and subdirectories.","permissions":["write-all","scope-download-recursive"]},"allow-exe-meta":{"identifier":"allow-exe-meta","description":"This allows non-recursive read access to metadata of the `$EXE` folder, including file listing and statistics.","permissions":["read-meta","scope-exe-index"]},"allow-exe-meta-recursive":{"identifier":"allow-exe-meta-recursive","description":"This allows full recursive read access to metadata of the `$EXE` folder, including file listing and statistics.","permissions":["read-meta","scope-exe-recursive"]},"allow-exe-read":{"identifier":"allow-exe-read","description":"This allows non-recursive read access to the `$EXE` folder.","permissions":["read-all","scope-exe"]},"allow-exe-read-recursive":{"identifier":"allow-exe-read-recursive","description":"This allows full recursive read access to the complete `$EXE` folder, files and subdirectories.","permissions":["read-all","scope-exe-recursive"]},"allow-exe-write":{"identifier":"allow-exe-write","description":"This allows non-recursive write access to the `$EXE` folder.","permissions":["write-all","scope-exe"]},"allow-exe-write-recursive":{"identifier":"allow-exe-write-recursive","description":"This allows full recursive write access to the complete `$EXE` folder, files and subdirectories.","permissions":["write-all","scope-exe-recursive"]},"allow-font-meta":{"identifier":"allow-font-meta","description":"This allows non-recursive read access to metadata of the `$FONT` folder, including file listing and statistics.","permissions":["read-meta","scope-font-index"]},"allow-font-meta-recursive":{"identifier":"allow-font-meta-recursive","description":"This allows full recursive read access to metadata of the `$FONT` folder, including file listing and statistics.","permissions":["read-meta","scope-font-recursive"]},"allow-font-read":{"identifier":"allow-font-read","description":"This allows non-recursive read access to the `$FONT` folder.","permissions":["read-all","scope-font"]},"allow-font-read-recursive":{"identifier":"allow-font-read-recursive","description":"This allows full recursive read access to the complete `$FONT` folder, files and subdirectories.","permissions":["read-all","scope-font-recursive"]},"allow-font-write":{"identifier":"allow-font-write","description":"This allows non-recursive write access to the `$FONT` folder.","permissions":["write-all","scope-font"]},"allow-font-write-recursive":{"identifier":"allow-font-write-recursive","description":"This allows full recursive write access to the complete `$FONT` folder, files and subdirectories.","permissions":["write-all","scope-font-recursive"]},"allow-home-meta":{"identifier":"allow-home-meta","description":"This allows non-recursive read access to metadata of the `$HOME` folder, including file listing and statistics.","permissions":["read-meta","scope-home-index"]},"allow-home-meta-recursive":{"identifier":"allow-home-meta-recursive","description":"This allows full recursive read access to metadata of the `$HOME` folder, including file listing and statistics.","permissions":["read-meta","scope-home-recursive"]},"allow-home-read":{"identifier":"allow-home-read","description":"This allows non-recursive read access to the `$HOME` folder.","permissions":["read-all","scope-home"]},"allow-home-read-recursive":{"identifier":"allow-home-read-recursive","description":"This allows full recursive read access to the complete `$HOME` folder, files and subdirectories.","permissions":["read-all","scope-home-recursive"]},"allow-home-write":{"identifier":"allow-home-write","description":"This allows non-recursive write access to the `$HOME` folder.","permissions":["write-all","scope-home"]},"allow-home-write-recursive":{"identifier":"allow-home-write-recursive","description":"This allows full recursive write access to the complete `$HOME` folder, files and subdirectories.","permissions":["write-all","scope-home-recursive"]},"allow-localdata-meta":{"identifier":"allow-localdata-meta","description":"This allows non-recursive read access to metadata of the `$LOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-localdata-index"]},"allow-localdata-meta-recursive":{"identifier":"allow-localdata-meta-recursive","description":"This allows full recursive read access to metadata of the `$LOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-localdata-recursive"]},"allow-localdata-read":{"identifier":"allow-localdata-read","description":"This allows non-recursive read access to the `$LOCALDATA` folder.","permissions":["read-all","scope-localdata"]},"allow-localdata-read-recursive":{"identifier":"allow-localdata-read-recursive","description":"This allows full recursive read access to the complete `$LOCALDATA` folder, files and subdirectories.","permissions":["read-all","scope-localdata-recursive"]},"allow-localdata-write":{"identifier":"allow-localdata-write","description":"This allows non-recursive write access to the `$LOCALDATA` folder.","permissions":["write-all","scope-localdata"]},"allow-localdata-write-recursive":{"identifier":"allow-localdata-write-recursive","description":"This allows full recursive write access to the complete `$LOCALDATA` folder, files and subdirectories.","permissions":["write-all","scope-localdata-recursive"]},"allow-log-meta":{"identifier":"allow-log-meta","description":"This allows non-recursive read access to metadata of the `$LOG` folder, including file listing and statistics.","permissions":["read-meta","scope-log-index"]},"allow-log-meta-recursive":{"identifier":"allow-log-meta-recursive","description":"This allows full recursive read access to metadata of the `$LOG` folder, including file listing and statistics.","permissions":["read-meta","scope-log-recursive"]},"allow-log-read":{"identifier":"allow-log-read","description":"This allows non-recursive read access to the `$LOG` folder.","permissions":["read-all","scope-log"]},"allow-log-read-recursive":{"identifier":"allow-log-read-recursive","description":"This allows full recursive read access to the complete `$LOG` folder, files and subdirectories.","permissions":["read-all","scope-log-recursive"]},"allow-log-write":{"identifier":"allow-log-write","description":"This allows non-recursive write access to the `$LOG` folder.","permissions":["write-all","scope-log"]},"allow-log-write-recursive":{"identifier":"allow-log-write-recursive","description":"This allows full recursive write access to the complete `$LOG` folder, files and subdirectories.","permissions":["write-all","scope-log-recursive"]},"allow-picture-meta":{"identifier":"allow-picture-meta","description":"This allows non-recursive read access to metadata of the `$PICTURE` folder, including file listing and statistics.","permissions":["read-meta","scope-picture-index"]},"allow-picture-meta-recursive":{"identifier":"allow-picture-meta-recursive","description":"This allows full recursive read access to metadata of the `$PICTURE` folder, including file listing and statistics.","permissions":["read-meta","scope-picture-recursive"]},"allow-picture-read":{"identifier":"allow-picture-read","description":"This allows non-recursive read access to the `$PICTURE` folder.","permissions":["read-all","scope-picture"]},"allow-picture-read-recursive":{"identifier":"allow-picture-read-recursive","description":"This allows full recursive read access to the complete `$PICTURE` folder, files and subdirectories.","permissions":["read-all","scope-picture-recursive"]},"allow-picture-write":{"identifier":"allow-picture-write","description":"This allows non-recursive write access to the `$PICTURE` folder.","permissions":["write-all","scope-picture"]},"allow-picture-write-recursive":{"identifier":"allow-picture-write-recursive","description":"This allows full recursive write access to the complete `$PICTURE` folder, files and subdirectories.","permissions":["write-all","scope-picture-recursive"]},"allow-public-meta":{"identifier":"allow-public-meta","description":"This allows non-recursive read access to metadata of the `$PUBLIC` folder, including file listing and statistics.","permissions":["read-meta","scope-public-index"]},"allow-public-meta-recursive":{"identifier":"allow-public-meta-recursive","description":"This allows full recursive read access to metadata of the `$PUBLIC` folder, including file listing and statistics.","permissions":["read-meta","scope-public-recursive"]},"allow-public-read":{"identifier":"allow-public-read","description":"This allows non-recursive read access to the `$PUBLIC` folder.","permissions":["read-all","scope-public"]},"allow-public-read-recursive":{"identifier":"allow-public-read-recursive","description":"This allows full recursive read access to the complete `$PUBLIC` folder, files and subdirectories.","permissions":["read-all","scope-public-recursive"]},"allow-public-write":{"identifier":"allow-public-write","description":"This allows non-recursive write access to the `$PUBLIC` folder.","permissions":["write-all","scope-public"]},"allow-public-write-recursive":{"identifier":"allow-public-write-recursive","description":"This allows full recursive write access to the complete `$PUBLIC` folder, files and subdirectories.","permissions":["write-all","scope-public-recursive"]},"allow-resource-meta":{"identifier":"allow-resource-meta","description":"This allows non-recursive read access to metadata of the `$RESOURCE` folder, including file listing and statistics.","permissions":["read-meta","scope-resource-index"]},"allow-resource-meta-recursive":{"identifier":"allow-resource-meta-recursive","description":"This allows full recursive read access to metadata of the `$RESOURCE` folder, including file listing and statistics.","permissions":["read-meta","scope-resource-recursive"]},"allow-resource-read":{"identifier":"allow-resource-read","description":"This allows non-recursive read access to the `$RESOURCE` folder.","permissions":["read-all","scope-resource"]},"allow-resource-read-recursive":{"identifier":"allow-resource-read-recursive","description":"This allows full recursive read access to the complete `$RESOURCE` folder, files and subdirectories.","permissions":["read-all","scope-resource-recursive"]},"allow-resource-write":{"identifier":"allow-resource-write","description":"This allows non-recursive write access to the `$RESOURCE` folder.","permissions":["write-all","scope-resource"]},"allow-resource-write-recursive":{"identifier":"allow-resource-write-recursive","description":"This allows full recursive write access to the complete `$RESOURCE` folder, files and subdirectories.","permissions":["write-all","scope-resource-recursive"]},"allow-runtime-meta":{"identifier":"allow-runtime-meta","description":"This allows non-recursive read access to metadata of the `$RUNTIME` folder, including file listing and statistics.","permissions":["read-meta","scope-runtime-index"]},"allow-runtime-meta-recursive":{"identifier":"allow-runtime-meta-recursive","description":"This allows full recursive read access to metadata of the `$RUNTIME` folder, including file listing and statistics.","permissions":["read-meta","scope-runtime-recursive"]},"allow-runtime-read":{"identifier":"allow-runtime-read","description":"This allows non-recursive read access to the `$RUNTIME` folder.","permissions":["read-all","scope-runtime"]},"allow-runtime-read-recursive":{"identifier":"allow-runtime-read-recursive","description":"This allows full recursive read access to the complete `$RUNTIME` folder, files and subdirectories.","permissions":["read-all","scope-runtime-recursive"]},"allow-runtime-write":{"identifier":"allow-runtime-write","description":"This allows non-recursive write access to the `$RUNTIME` folder.","permissions":["write-all","scope-runtime"]},"allow-runtime-write-recursive":{"identifier":"allow-runtime-write-recursive","description":"This allows full recursive write access to the complete `$RUNTIME` folder, files and subdirectories.","permissions":["write-all","scope-runtime-recursive"]},"allow-temp-meta":{"identifier":"allow-temp-meta","description":"This allows non-recursive read access to metadata of the `$TEMP` folder, including file listing and statistics.","permissions":["read-meta","scope-temp-index"]},"allow-temp-meta-recursive":{"identifier":"allow-temp-meta-recursive","description":"This allows full recursive read access to metadata of the `$TEMP` folder, including file listing and statistics.","permissions":["read-meta","scope-temp-recursive"]},"allow-temp-read":{"identifier":"allow-temp-read","description":"This allows non-recursive read access to the `$TEMP` folder.","permissions":["read-all","scope-temp"]},"allow-temp-read-recursive":{"identifier":"allow-temp-read-recursive","description":"This allows full recursive read access to the complete `$TEMP` folder, files and subdirectories.","permissions":["read-all","scope-temp-recursive"]},"allow-temp-write":{"identifier":"allow-temp-write","description":"This allows non-recursive write access to the `$TEMP` folder.","permissions":["write-all","scope-temp"]},"allow-temp-write-recursive":{"identifier":"allow-temp-write-recursive","description":"This allows full recursive write access to the complete `$TEMP` folder, files and subdirectories.","permissions":["write-all","scope-temp-recursive"]},"allow-template-meta":{"identifier":"allow-template-meta","description":"This allows non-recursive read access to metadata of the `$TEMPLATE` folder, including file listing and statistics.","permissions":["read-meta","scope-template-index"]},"allow-template-meta-recursive":{"identifier":"allow-template-meta-recursive","description":"This allows full recursive read access to metadata of the `$TEMPLATE` folder, including file listing and statistics.","permissions":["read-meta","scope-template-recursive"]},"allow-template-read":{"identifier":"allow-template-read","description":"This allows non-recursive read access to the `$TEMPLATE` folder.","permissions":["read-all","scope-template"]},"allow-template-read-recursive":{"identifier":"allow-template-read-recursive","description":"This allows full recursive read access to the complete `$TEMPLATE` folder, files and subdirectories.","permissions":["read-all","scope-template-recursive"]},"allow-template-write":{"identifier":"allow-template-write","description":"This allows non-recursive write access to the `$TEMPLATE` folder.","permissions":["write-all","scope-template"]},"allow-template-write-recursive":{"identifier":"allow-template-write-recursive","description":"This allows full recursive write access to the complete `$TEMPLATE` folder, files and subdirectories.","permissions":["write-all","scope-template-recursive"]},"allow-video-meta":{"identifier":"allow-video-meta","description":"This allows non-recursive read access to metadata of the `$VIDEO` folder, including file listing and statistics.","permissions":["read-meta","scope-video-index"]},"allow-video-meta-recursive":{"identifier":"allow-video-meta-recursive","description":"This allows full recursive read access to metadata of the `$VIDEO` folder, including file listing and statistics.","permissions":["read-meta","scope-video-recursive"]},"allow-video-read":{"identifier":"allow-video-read","description":"This allows non-recursive read access to the `$VIDEO` folder.","permissions":["read-all","scope-video"]},"allow-video-read-recursive":{"identifier":"allow-video-read-recursive","description":"This allows full recursive read access to the complete `$VIDEO` folder, files and subdirectories.","permissions":["read-all","scope-video-recursive"]},"allow-video-write":{"identifier":"allow-video-write","description":"This allows non-recursive write access to the `$VIDEO` folder.","permissions":["write-all","scope-video"]},"allow-video-write-recursive":{"identifier":"allow-video-write-recursive","description":"This allows full recursive write access to the complete `$VIDEO` folder, files and subdirectories.","permissions":["write-all","scope-video-recursive"]},"deny-default":{"identifier":"deny-default","description":"This denies access to dangerous Tauri relevant files and folders by default.","permissions":["deny-webview-data-linux","deny-webview-data-windows"]}},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"description":"A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},{"properties":{"path":{"description":"A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"description":"FS scope entry.","title":"FsScopeEntry"}},"log":{"default_permission":{"identifier":"default","description":"Allows the log command","permissions":["allow-log"]},"permissions":{"allow-log":{"identifier":"allow-log","description":"Enables the log command without any pre-configured scope.","commands":{"allow":["log"],"deny":[]}},"deny-log":{"identifier":"deny-log","description":"Denies the log command without any pre-configured scope.","commands":{"allow":[],"deny":["log"]}}},"permission_sets":{},"global_scope_schema":null},"opener":{"default_permission":{"identifier":"default","description":"This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer","permissions":["allow-open-url","allow-reveal-item-in-dir","allow-default-urls"]},"permissions":{"allow-default-urls":{"identifier":"allow-default-urls","description":"This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"url":"mailto:*"},{"url":"tel:*"},{"url":"http://*"},{"url":"https://*"}]}},"allow-open-path":{"identifier":"allow-open-path","description":"Enables the open_path command without any pre-configured scope.","commands":{"allow":["open_path"],"deny":[]}},"allow-open-url":{"identifier":"allow-open-url","description":"Enables the open_url command without any pre-configured scope.","commands":{"allow":["open_url"],"deny":[]}},"allow-reveal-item-in-dir":{"identifier":"allow-reveal-item-in-dir","description":"Enables the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":["reveal_item_in_dir"],"deny":[]}},"deny-open-path":{"identifier":"deny-open-path","description":"Denies the open_path command without any pre-configured scope.","commands":{"allow":[],"deny":["open_path"]}},"deny-open-url":{"identifier":"deny-open-url","description":"Denies the open_url command without any pre-configured scope.","commands":{"allow":[],"deny":["open_url"]}},"deny-reveal-item-in-dir":{"identifier":"deny-reveal-item-in-dir","description":"Denies the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["reveal_item_in_dir"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this url with, for example: firefox."},"url":{"description":"A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.amrom.workers.dev/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"","type":"string"}},"required":["url"],"type":"object"},{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this path with, for example: xdg-open."},"path":{"description":"A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"definitions":{"Application":{"anyOf":[{"description":"Open in default application.","type":"null"},{"description":"If true, allow open with any application.","type":"boolean"},{"description":"Allow specific application to open with.","type":"string"}],"description":"Opener scope application."}},"description":"Opener scope entry.","title":"OpenerScopeEntry"}},"os":{"default_permission":{"identifier":"default","description":"This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n","permissions":["allow-arch","allow-exe-extension","allow-family","allow-locale","allow-os-type","allow-platform","allow-version"]},"permissions":{"allow-arch":{"identifier":"allow-arch","description":"Enables the arch command without any pre-configured scope.","commands":{"allow":["arch"],"deny":[]}},"allow-exe-extension":{"identifier":"allow-exe-extension","description":"Enables the exe_extension command without any pre-configured scope.","commands":{"allow":["exe_extension"],"deny":[]}},"allow-family":{"identifier":"allow-family","description":"Enables the family command without any pre-configured scope.","commands":{"allow":["family"],"deny":[]}},"allow-hostname":{"identifier":"allow-hostname","description":"Enables the hostname command without any pre-configured scope.","commands":{"allow":["hostname"],"deny":[]}},"allow-locale":{"identifier":"allow-locale","description":"Enables the locale command without any pre-configured scope.","commands":{"allow":["locale"],"deny":[]}},"allow-os-type":{"identifier":"allow-os-type","description":"Enables the os_type command without any pre-configured scope.","commands":{"allow":["os_type"],"deny":[]}},"allow-platform":{"identifier":"allow-platform","description":"Enables the platform command without any pre-configured scope.","commands":{"allow":["platform"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-arch":{"identifier":"deny-arch","description":"Denies the arch command without any pre-configured scope.","commands":{"allow":[],"deny":["arch"]}},"deny-exe-extension":{"identifier":"deny-exe-extension","description":"Denies the exe_extension command without any pre-configured scope.","commands":{"allow":[],"deny":["exe_extension"]}},"deny-family":{"identifier":"deny-family","description":"Denies the family command without any pre-configured scope.","commands":{"allow":[],"deny":["family"]}},"deny-hostname":{"identifier":"deny-hostname","description":"Denies the hostname command without any pre-configured scope.","commands":{"allow":[],"deny":["hostname"]}},"deny-locale":{"identifier":"deny-locale","description":"Denies the locale command without any pre-configured scope.","commands":{"allow":[],"deny":["locale"]}},"deny-os-type":{"identifier":"deny-os-type","description":"Denies the os_type command without any pre-configured scope.","commands":{"allow":[],"deny":["os_type"]}},"deny-platform":{"identifier":"deny-platform","description":"Denies the platform command without any pre-configured scope.","commands":{"allow":[],"deny":["platform"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"}},"required":["cmd","name"],"type":"object"},{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["name","sidecar"],"type":"object"}],"definitions":{"ShellScopeEntryAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"raw":{"default":false,"description":"Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.","type":"boolean"},"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellScopeEntryAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellScopeEntryAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"Shell scope entry.","title":"ShellScopeEntry"}},"updater":{"default_permission":{"identifier":"default","description":"This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n","permissions":["allow-check","allow-download","allow-install","allow-download-and-install"]},"permissions":{"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"allow-download":{"identifier":"allow-download","description":"Enables the download command without any pre-configured scope.","commands":{"allow":["download"],"deny":[]}},"allow-download-and-install":{"identifier":"allow-download-and-install","description":"Enables the download_and_install command without any pre-configured scope.","commands":{"allow":["download_and_install"],"deny":[]}},"allow-install":{"identifier":"allow-install","description":"Enables the install command without any pre-configured scope.","commands":{"allow":["install"],"deny":[]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}},"deny-download":{"identifier":"deny-download","description":"Denies the download command without any pre-configured scope.","commands":{"allow":[],"deny":["download"]}},"deny-download-and-install":{"identifier":"deny-download-and-install","description":"Denies the download_and_install command without any pre-configured scope.","commands":{"allow":[],"deny":["download_and_install"]}},"deny-install":{"identifier":"deny-install","description":"Denies the install command without any pre-configured scope.","commands":{"allow":[],"deny":["install"]}}},"permission_sets":{},"global_scope_schema":null},"window-state":{"default_permission":{"identifier":"default","description":"This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n","permissions":["allow-filename","allow-restore-state","allow-save-window-state"]},"permissions":{"allow-filename":{"identifier":"allow-filename","description":"Enables the filename command without any pre-configured scope.","commands":{"allow":["filename"],"deny":[]}},"allow-restore-state":{"identifier":"allow-restore-state","description":"Enables the restore_state command without any pre-configured scope.","commands":{"allow":["restore_state"],"deny":[]}},"allow-save-window-state":{"identifier":"allow-save-window-state","description":"Enables the save_window_state command without any pre-configured scope.","commands":{"allow":["save_window_state"],"deny":[]}},"deny-filename":{"identifier":"deny-filename","description":"Denies the filename command without any pre-configured scope.","commands":{"allow":[],"deny":["filename"]}},"deny-restore-state":{"identifier":"deny-restore-state","description":"Denies the restore_state command without any pre-configured scope.","commands":{"allow":[],"deny":["restore_state"]}},"deny-save-window-state":{"identifier":"deny-save-window-state","description":"Denies the save_window_state command without any pre-configured scope.","commands":{"allow":[],"deny":["save_window_state"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-git":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-add","allow-branch","allow-checkout","allow-commit","allow-delete-branch","allow-fetch-all","allow-initialize","allow-log","allow-merge-branch","allow-pull","allow-push","allow-status","allow-unstage"]},"permissions":{"allow-add":{"identifier":"allow-add","description":"Enables the add command without any pre-configured scope.","commands":{"allow":["add"],"deny":[]}},"allow-branch":{"identifier":"allow-branch","description":"Enables the branch command without any pre-configured scope.","commands":{"allow":["branch"],"deny":[]}},"allow-checkout":{"identifier":"allow-checkout","description":"Enables the checkout command without any pre-configured scope.","commands":{"allow":["checkout"],"deny":[]}},"allow-checkout-remote":{"identifier":"allow-checkout-remote","description":"Enables the checkout_remote command without any pre-configured scope.","commands":{"allow":["checkout_remote"],"deny":[]}},"allow-commit":{"identifier":"allow-commit","description":"Enables the commit command without any pre-configured scope.","commands":{"allow":["commit"],"deny":[]}},"allow-delete-branch":{"identifier":"allow-delete-branch","description":"Enables the delete_branch command without any pre-configured scope.","commands":{"allow":["delete_branch"],"deny":[]}},"allow-fetch-all":{"identifier":"allow-fetch-all","description":"Enables the fetch_all command without any pre-configured scope.","commands":{"allow":["fetch_all"],"deny":[]}},"allow-initialize":{"identifier":"allow-initialize","description":"Enables the initialize command without any pre-configured scope.","commands":{"allow":["initialize"],"deny":[]}},"allow-log":{"identifier":"allow-log","description":"Enables the log command without any pre-configured scope.","commands":{"allow":["log"],"deny":[]}},"allow-merge-branch":{"identifier":"allow-merge-branch","description":"Enables the merge_branch command without any pre-configured scope.","commands":{"allow":["merge_branch"],"deny":[]}},"allow-pull":{"identifier":"allow-pull","description":"Enables the pull command without any pre-configured scope.","commands":{"allow":["pull"],"deny":[]}},"allow-push":{"identifier":"allow-push","description":"Enables the push command without any pre-configured scope.","commands":{"allow":["push"],"deny":[]}},"allow-status":{"identifier":"allow-status","description":"Enables the status command without any pre-configured scope.","commands":{"allow":["status"],"deny":[]}},"allow-unstage":{"identifier":"allow-unstage","description":"Enables the unstage command without any pre-configured scope.","commands":{"allow":["unstage"],"deny":[]}},"deny-add":{"identifier":"deny-add","description":"Denies the add command without any pre-configured scope.","commands":{"allow":[],"deny":["add"]}},"deny-branch":{"identifier":"deny-branch","description":"Denies the branch command without any pre-configured scope.","commands":{"allow":[],"deny":["branch"]}},"deny-checkout":{"identifier":"deny-checkout","description":"Denies the checkout command without any pre-configured scope.","commands":{"allow":[],"deny":["checkout"]}},"deny-checkout-remote":{"identifier":"deny-checkout-remote","description":"Denies the checkout_remote command without any pre-configured scope.","commands":{"allow":[],"deny":["checkout_remote"]}},"deny-commit":{"identifier":"deny-commit","description":"Denies the commit command without any pre-configured scope.","commands":{"allow":[],"deny":["commit"]}},"deny-delete-branch":{"identifier":"deny-delete-branch","description":"Denies the delete_branch command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_branch"]}},"deny-fetch-all":{"identifier":"deny-fetch-all","description":"Denies the fetch_all command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_all"]}},"deny-initialize":{"identifier":"deny-initialize","description":"Denies the initialize command without any pre-configured scope.","commands":{"allow":[],"deny":["initialize"]}},"deny-log":{"identifier":"deny-log","description":"Denies the log command without any pre-configured scope.","commands":{"allow":[],"deny":["log"]}},"deny-merge-branch":{"identifier":"deny-merge-branch","description":"Denies the merge_branch command without any pre-configured scope.","commands":{"allow":[],"deny":["merge_branch"]}},"deny-pull":{"identifier":"deny-pull","description":"Denies the pull command without any pre-configured scope.","commands":{"allow":[],"deny":["pull"]}},"deny-push":{"identifier":"deny-push","description":"Denies the push command without any pre-configured scope.","commands":{"allow":[],"deny":["push"]}},"deny-status":{"identifier":"deny-status","description":"Denies the status command without any pre-configured scope.","commands":{"allow":[],"deny":["status"]}},"deny-unstage":{"identifier":"deny-unstage","description":"Denies the unstage command without any pre-configured scope.","commands":{"allow":[],"deny":["unstage"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-license":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-check","allow-activate","allow-deactivate"]},"permissions":{"allow-activate":{"identifier":"allow-activate","description":"Enables the activate command without any pre-configured scope.","commands":{"allow":["activate"],"deny":[]}},"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"allow-deactivate":{"identifier":"allow-deactivate","description":"Enables the deactivate command without any pre-configured scope.","commands":{"allow":["deactivate"],"deny":[]}},"deny-activate":{"identifier":"deny-activate","description":"Denies the activate command without any pre-configured scope.","commands":{"allow":[],"deny":["activate"]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}},"deny-deactivate":{"identifier":"deny-deactivate","description":"Denies the deactivate command without any pre-configured scope.","commands":{"allow":[],"deny":["deactivate"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-sync":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-calculate","allow-calculate-fs","allow-apply","allow-watch"]},"permissions":{"allow-apply":{"identifier":"allow-apply","description":"Enables the apply command without any pre-configured scope.","commands":{"allow":["apply"],"deny":[]}},"allow-calculate":{"identifier":"allow-calculate","description":"Enables the calculate command without any pre-configured scope.","commands":{"allow":["calculate"],"deny":[]}},"allow-calculate-fs":{"identifier":"allow-calculate-fs","description":"Enables the calculate_fs command without any pre-configured scope.","commands":{"allow":["calculate_fs"],"deny":[]}},"allow-watch":{"identifier":"allow-watch","description":"Enables the watch command without any pre-configured scope.","commands":{"allow":["watch"],"deny":[]}},"deny-apply":{"identifier":"deny-apply","description":"Denies the apply command without any pre-configured scope.","commands":{"allow":[],"deny":["apply"]}},"deny-calculate":{"identifier":"deny-calculate","description":"Denies the calculate command without any pre-configured scope.","commands":{"allow":[],"deny":["calculate"]}},"deny-calculate-fs":{"identifier":"deny-calculate-fs","description":"Denies the calculate_fs command without any pre-configured scope.","commands":{"allow":[],"deny":["calculate_fs"]}},"deny-watch":{"identifier":"deny-watch","description":"Denies the watch command without any pre-configured scope.","commands":{"allow":[],"deny":["watch"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-ws":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-close","allow-connect","allow-delete-connection","allow-delete-connections","allow-delete-request","allow-duplicate-request","allow-list-connections","allow-list-events","allow-list-requests","allow-send","allow-upsert-request"]},"permissions":{"allow-cancel":{"identifier":"allow-cancel","description":"Enables the cancel command without any pre-configured scope.","commands":{"allow":["cancel"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-connect":{"identifier":"allow-connect","description":"Enables the connect command without any pre-configured scope.","commands":{"allow":["connect"],"deny":[]}},"allow-delete-connection":{"identifier":"allow-delete-connection","description":"Enables the delete_connection command without any pre-configured scope.","commands":{"allow":["delete_connection"],"deny":[]}},"allow-delete-connections":{"identifier":"allow-delete-connections","description":"Enables the delete_connections command without any pre-configured scope.","commands":{"allow":["delete_connections"],"deny":[]}},"allow-delete-request":{"identifier":"allow-delete-request","description":"Enables the delete_request command without any pre-configured scope.","commands":{"allow":["delete_request"],"deny":[]}},"allow-duplicate-request":{"identifier":"allow-duplicate-request","description":"Enables the duplicate_request command without any pre-configured scope.","commands":{"allow":["duplicate_request"],"deny":[]}},"allow-list-connections":{"identifier":"allow-list-connections","description":"Enables the list_connections command without any pre-configured scope.","commands":{"allow":["list_connections"],"deny":[]}},"allow-list-events":{"identifier":"allow-list-events","description":"Enables the list_events command without any pre-configured scope.","commands":{"allow":["list_events"],"deny":[]}},"allow-list-requests":{"identifier":"allow-list-requests","description":"Enables the list_requests command without any pre-configured scope.","commands":{"allow":["list_requests"],"deny":[]}},"allow-list-websocket-connections":{"identifier":"allow-list-websocket-connections","description":"Enables the list_websocket_connections command without any pre-configured scope.","commands":{"allow":["list_websocket_connections"],"deny":[]}},"allow-list-websocket-requests":{"identifier":"allow-list-websocket-requests","description":"Enables the list_websocket_requests command without any pre-configured scope.","commands":{"allow":["list_websocket_requests"],"deny":[]}},"allow-send":{"identifier":"allow-send","description":"Enables the send command without any pre-configured scope.","commands":{"allow":["send"],"deny":[]}},"allow-upsert-request":{"identifier":"allow-upsert-request","description":"Enables the upsert_request command without any pre-configured scope.","commands":{"allow":["upsert_request"],"deny":[]}},"allow-upsert-websocket-request":{"identifier":"allow-upsert-websocket-request","description":"Enables the upsert_websocket_request command without any pre-configured scope.","commands":{"allow":["upsert_websocket_request"],"deny":[]}},"deny-cancel":{"identifier":"deny-cancel","description":"Denies the cancel command without any pre-configured scope.","commands":{"allow":[],"deny":["cancel"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-connect":{"identifier":"deny-connect","description":"Denies the connect command without any pre-configured scope.","commands":{"allow":[],"deny":["connect"]}},"deny-delete-connection":{"identifier":"deny-delete-connection","description":"Denies the delete_connection command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_connection"]}},"deny-delete-connections":{"identifier":"deny-delete-connections","description":"Denies the delete_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_connections"]}},"deny-delete-request":{"identifier":"deny-delete-request","description":"Denies the delete_request command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_request"]}},"deny-duplicate-request":{"identifier":"deny-duplicate-request","description":"Denies the duplicate_request command without any pre-configured scope.","commands":{"allow":[],"deny":["duplicate_request"]}},"deny-list-connections":{"identifier":"deny-list-connections","description":"Denies the list_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["list_connections"]}},"deny-list-events":{"identifier":"deny-list-events","description":"Denies the list_events command without any pre-configured scope.","commands":{"allow":[],"deny":["list_events"]}},"deny-list-requests":{"identifier":"deny-list-requests","description":"Denies the list_requests command without any pre-configured scope.","commands":{"allow":[],"deny":["list_requests"]}},"deny-list-websocket-connections":{"identifier":"deny-list-websocket-connections","description":"Denies the list_websocket_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["list_websocket_connections"]}},"deny-list-websocket-requests":{"identifier":"deny-list-websocket-requests","description":"Denies the list_websocket_requests command without any pre-configured scope.","commands":{"allow":[],"deny":["list_websocket_requests"]}},"deny-send":{"identifier":"deny-send","description":"Denies the send command without any pre-configured scope.","commands":{"allow":[],"deny":["send"]}},"deny-upsert-request":{"identifier":"deny-upsert-request","description":"Denies the upsert_request command without any pre-configured scope.","commands":{"allow":[],"deny":["upsert_request"]}},"deny-upsert-websocket-request":{"identifier":"deny-upsert-websocket-request","description":"Denies the upsert_websocket_request command without any pre-configured scope.","commands":{"allow":[],"deny":["upsert_websocket_request"]}}},"permission_sets":{},"global_scope_schema":null}} \ No newline at end of file +{"clipboard-manager":{"default_permission":{"identifier":"default","description":"No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n","permissions":[]},"permissions":{"allow-clear":{"identifier":"allow-clear","description":"Enables the clear command without any pre-configured scope.","commands":{"allow":["clear"],"deny":[]}},"allow-read-image":{"identifier":"allow-read-image","description":"Enables the read_image command without any pre-configured scope.","commands":{"allow":["read_image"],"deny":[]}},"allow-read-text":{"identifier":"allow-read-text","description":"Enables the read_text command without any pre-configured scope.","commands":{"allow":["read_text"],"deny":[]}},"allow-write-html":{"identifier":"allow-write-html","description":"Enables the write_html command without any pre-configured scope.","commands":{"allow":["write_html"],"deny":[]}},"allow-write-image":{"identifier":"allow-write-image","description":"Enables the write_image command without any pre-configured scope.","commands":{"allow":["write_image"],"deny":[]}},"allow-write-text":{"identifier":"allow-write-text","description":"Enables the write_text command without any pre-configured scope.","commands":{"allow":["write_text"],"deny":[]}},"deny-clear":{"identifier":"deny-clear","description":"Denies the clear command without any pre-configured scope.","commands":{"allow":[],"deny":["clear"]}},"deny-read-image":{"identifier":"deny-read-image","description":"Denies the read_image command without any pre-configured scope.","commands":{"allow":[],"deny":["read_image"]}},"deny-read-text":{"identifier":"deny-read-text","description":"Denies the read_text command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text"]}},"deny-write-html":{"identifier":"deny-write-html","description":"Denies the write_html command without any pre-configured scope.","commands":{"allow":[],"deny":["write_html"]}},"deny-write-image":{"identifier":"deny-write-image","description":"Denies the write_image command without any pre-configured scope.","commands":{"allow":[],"deny":["write_image"]}},"deny-write-text":{"identifier":"deny-write-text","description":"Denies the write_text command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text"]}}},"permission_sets":{},"global_scope_schema":null},"core":{"default_permission":{"identifier":"default","description":"Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version","allow-identifier"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-fetch-data-store-identifiers":{"identifier":"allow-fetch-data-store-identifiers","description":"Enables the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":["fetch_data_store_identifiers"],"deny":[]}},"allow-identifier":{"identifier":"allow-identifier","description":"Enables the identifier command without any pre-configured scope.","commands":{"allow":["identifier"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-remove-data-store":{"identifier":"allow-remove-data-store","description":"Enables the remove_data_store command without any pre-configured scope.","commands":{"allow":["remove_data_store"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-fetch-data-store-identifiers":{"identifier":"deny-fetch-data-store-identifiers","description":"Denies the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_data_store_identifiers"]}},"deny-identifier":{"identifier":"deny-identifier","description":"Denies the identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["identifier"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-remove-data-store":{"identifier":"deny-remove-data-store","description":"Denies the remove_data_store command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_data_store"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-is-always-on-top","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-always-on-top":{"identifier":"allow-is-always-on-top","description":"Enables the is_always_on_top command without any pre-configured scope.","commands":{"allow":["is_always_on_top"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-always-on-top":{"identifier":"deny-is-always-on-top","description":"Denies the is_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["is_always_on_top"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-ask","allow-confirm","allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope.","commands":{"allow":["ask"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope.","commands":{"allow":["confirm"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope.","commands":{"allow":[],"deny":["ask"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope.","commands":{"allow":[],"deny":["confirm"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"fs":{"default_permission":{"identifier":"default","description":"This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n","permissions":["create-app-specific-dirs","read-app-specific-dirs-recursive","deny-default"]},"permissions":{"allow-copy-file":{"identifier":"allow-copy-file","description":"Enables the copy_file command without any pre-configured scope.","commands":{"allow":["copy_file"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-exists":{"identifier":"allow-exists","description":"Enables the exists command without any pre-configured scope.","commands":{"allow":["exists"],"deny":[]}},"allow-fstat":{"identifier":"allow-fstat","description":"Enables the fstat command without any pre-configured scope.","commands":{"allow":["fstat"],"deny":[]}},"allow-ftruncate":{"identifier":"allow-ftruncate","description":"Enables the ftruncate command without any pre-configured scope.","commands":{"allow":["ftruncate"],"deny":[]}},"allow-lstat":{"identifier":"allow-lstat","description":"Enables the lstat command without any pre-configured scope.","commands":{"allow":["lstat"],"deny":[]}},"allow-mkdir":{"identifier":"allow-mkdir","description":"Enables the mkdir command without any pre-configured scope.","commands":{"allow":["mkdir"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-read":{"identifier":"allow-read","description":"Enables the read command without any pre-configured scope.","commands":{"allow":["read"],"deny":[]}},"allow-read-dir":{"identifier":"allow-read-dir","description":"Enables the read_dir command without any pre-configured scope.","commands":{"allow":["read_dir"],"deny":[]}},"allow-read-file":{"identifier":"allow-read-file","description":"Enables the read_file command without any pre-configured scope.","commands":{"allow":["read_file"],"deny":[]}},"allow-read-text-file":{"identifier":"allow-read-text-file","description":"Enables the read_text_file command without any pre-configured scope.","commands":{"allow":["read_text_file"],"deny":[]}},"allow-read-text-file-lines":{"identifier":"allow-read-text-file-lines","description":"Enables the read_text_file_lines command without any pre-configured scope.","commands":{"allow":["read_text_file_lines","read_text_file_lines_next"],"deny":[]}},"allow-read-text-file-lines-next":{"identifier":"allow-read-text-file-lines-next","description":"Enables the read_text_file_lines_next command without any pre-configured scope.","commands":{"allow":["read_text_file_lines_next"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-rename":{"identifier":"allow-rename","description":"Enables the rename command without any pre-configured scope.","commands":{"allow":["rename"],"deny":[]}},"allow-seek":{"identifier":"allow-seek","description":"Enables the seek command without any pre-configured scope.","commands":{"allow":["seek"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"allow-stat":{"identifier":"allow-stat","description":"Enables the stat command without any pre-configured scope.","commands":{"allow":["stat"],"deny":[]}},"allow-truncate":{"identifier":"allow-truncate","description":"Enables the truncate command without any pre-configured scope.","commands":{"allow":["truncate"],"deny":[]}},"allow-unwatch":{"identifier":"allow-unwatch","description":"Enables the unwatch command without any pre-configured scope.","commands":{"allow":["unwatch"],"deny":[]}},"allow-watch":{"identifier":"allow-watch","description":"Enables the watch command without any pre-configured scope.","commands":{"allow":["watch"],"deny":[]}},"allow-write":{"identifier":"allow-write","description":"Enables the write command without any pre-configured scope.","commands":{"allow":["write"],"deny":[]}},"allow-write-file":{"identifier":"allow-write-file","description":"Enables the write_file command without any pre-configured scope.","commands":{"allow":["write_file","open","write"],"deny":[]}},"allow-write-text-file":{"identifier":"allow-write-text-file","description":"Enables the write_text_file command without any pre-configured scope.","commands":{"allow":["write_text_file"],"deny":[]}},"create-app-specific-dirs":{"identifier":"create-app-specific-dirs","description":"This permissions allows to create the application specific directories.\n","commands":{"allow":["mkdir","scope-app-index"],"deny":[]}},"deny-copy-file":{"identifier":"deny-copy-file","description":"Denies the copy_file command without any pre-configured scope.","commands":{"allow":[],"deny":["copy_file"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-exists":{"identifier":"deny-exists","description":"Denies the exists command without any pre-configured scope.","commands":{"allow":[],"deny":["exists"]}},"deny-fstat":{"identifier":"deny-fstat","description":"Denies the fstat command without any pre-configured scope.","commands":{"allow":[],"deny":["fstat"]}},"deny-ftruncate":{"identifier":"deny-ftruncate","description":"Denies the ftruncate command without any pre-configured scope.","commands":{"allow":[],"deny":["ftruncate"]}},"deny-lstat":{"identifier":"deny-lstat","description":"Denies the lstat command without any pre-configured scope.","commands":{"allow":[],"deny":["lstat"]}},"deny-mkdir":{"identifier":"deny-mkdir","description":"Denies the mkdir command without any pre-configured scope.","commands":{"allow":[],"deny":["mkdir"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-read":{"identifier":"deny-read","description":"Denies the read command without any pre-configured scope.","commands":{"allow":[],"deny":["read"]}},"deny-read-dir":{"identifier":"deny-read-dir","description":"Denies the read_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["read_dir"]}},"deny-read-file":{"identifier":"deny-read-file","description":"Denies the read_file command without any pre-configured scope.","commands":{"allow":[],"deny":["read_file"]}},"deny-read-text-file":{"identifier":"deny-read-text-file","description":"Denies the read_text_file command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file"]}},"deny-read-text-file-lines":{"identifier":"deny-read-text-file-lines","description":"Denies the read_text_file_lines command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file_lines"]}},"deny-read-text-file-lines-next":{"identifier":"deny-read-text-file-lines-next","description":"Denies the read_text_file_lines_next command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file_lines_next"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-rename":{"identifier":"deny-rename","description":"Denies the rename command without any pre-configured scope.","commands":{"allow":[],"deny":["rename"]}},"deny-seek":{"identifier":"deny-seek","description":"Denies the seek command without any pre-configured scope.","commands":{"allow":[],"deny":["seek"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}},"deny-stat":{"identifier":"deny-stat","description":"Denies the stat command without any pre-configured scope.","commands":{"allow":[],"deny":["stat"]}},"deny-truncate":{"identifier":"deny-truncate","description":"Denies the truncate command without any pre-configured scope.","commands":{"allow":[],"deny":["truncate"]}},"deny-unwatch":{"identifier":"deny-unwatch","description":"Denies the unwatch command without any pre-configured scope.","commands":{"allow":[],"deny":["unwatch"]}},"deny-watch":{"identifier":"deny-watch","description":"Denies the watch command without any pre-configured scope.","commands":{"allow":[],"deny":["watch"]}},"deny-webview-data-linux":{"identifier":"deny-webview-data-linux","description":"This denies read access to the\n`$APPLOCALDATA` folder on linux as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.","commands":{"allow":[],"deny":[]}},"deny-webview-data-windows":{"identifier":"deny-webview-data-windows","description":"This denies read access to the\n`$APPLOCALDATA/EBWebView` folder on windows as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.","commands":{"allow":[],"deny":[]}},"deny-write":{"identifier":"deny-write","description":"Denies the write command without any pre-configured scope.","commands":{"allow":[],"deny":["write"]}},"deny-write-file":{"identifier":"deny-write-file","description":"Denies the write_file command without any pre-configured scope.","commands":{"allow":[],"deny":["write_file"]}},"deny-write-text-file":{"identifier":"deny-write-text-file","description":"Denies the write_text_file command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text_file"]}},"read-all":{"identifier":"read-all","description":"This enables all read related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","read_file","read","open","read_text_file","read_text_file_lines","read_text_file_lines_next","seek","stat","lstat","fstat","exists","watch","unwatch"],"deny":[]}},"read-app-specific-dirs-recursive":{"identifier":"read-app-specific-dirs-recursive","description":"This permission allows recursive read functionality on the application\nspecific base directories. \n","commands":{"allow":["read_dir","read_file","read_text_file","read_text_file_lines","read_text_file_lines_next","exists","scope-app-recursive"],"deny":[]}},"read-dirs":{"identifier":"read-dirs","description":"This enables directory read and file metadata related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","stat","lstat","fstat","exists"],"deny":[]}},"read-files":{"identifier":"read-files","description":"This enables file read related commands without any pre-configured accessible paths.","commands":{"allow":["read_file","read","open","read_text_file","read_text_file_lines","read_text_file_lines_next","seek","stat","lstat","fstat","exists"],"deny":[]}},"read-meta":{"identifier":"read-meta","description":"This enables all index or metadata related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","stat","lstat","fstat","exists","size"],"deny":[]}},"scope":{"identifier":"scope","description":"An empty permission you can use to modify the global scope.","commands":{"allow":[],"deny":[]}},"scope-app":{"identifier":"scope-app","description":"This scope permits access to all files and list content of top level directories in the application folders.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/*"},{"path":"$APPDATA"},{"path":"$APPDATA/*"},{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/*"},{"path":"$APPCACHE"},{"path":"$APPCACHE/*"},{"path":"$APPLOG"},{"path":"$APPLOG/*"}]}},"scope-app-index":{"identifier":"scope-app-index","description":"This scope permits to list all files and folders in the application directories.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPDATA"},{"path":"$APPLOCALDATA"},{"path":"$APPCACHE"},{"path":"$APPLOG"}]}},"scope-app-recursive":{"identifier":"scope-app-recursive","description":"This scope permits recursive access to the complete application folders, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/**"},{"path":"$APPDATA"},{"path":"$APPDATA/**"},{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/**"},{"path":"$APPCACHE"},{"path":"$APPCACHE/**"},{"path":"$APPLOG"},{"path":"$APPLOG/**"}]}},"scope-appcache":{"identifier":"scope-appcache","description":"This scope permits access to all files and list content of top level directories in the `$APPCACHE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"},{"path":"$APPCACHE/*"}]}},"scope-appcache-index":{"identifier":"scope-appcache-index","description":"This scope permits to list all files and folders in the `$APPCACHE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"}]}},"scope-appcache-recursive":{"identifier":"scope-appcache-recursive","description":"This scope permits recursive access to the complete `$APPCACHE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"},{"path":"$APPCACHE/**"}]}},"scope-appconfig":{"identifier":"scope-appconfig","description":"This scope permits access to all files and list content of top level directories in the `$APPCONFIG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/*"}]}},"scope-appconfig-index":{"identifier":"scope-appconfig-index","description":"This scope permits to list all files and folders in the `$APPCONFIG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"}]}},"scope-appconfig-recursive":{"identifier":"scope-appconfig-recursive","description":"This scope permits recursive access to the complete `$APPCONFIG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/**"}]}},"scope-appdata":{"identifier":"scope-appdata","description":"This scope permits access to all files and list content of top level directories in the `$APPDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"},{"path":"$APPDATA/*"}]}},"scope-appdata-index":{"identifier":"scope-appdata-index","description":"This scope permits to list all files and folders in the `$APPDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"}]}},"scope-appdata-recursive":{"identifier":"scope-appdata-recursive","description":"This scope permits recursive access to the complete `$APPDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]}},"scope-applocaldata":{"identifier":"scope-applocaldata","description":"This scope permits access to all files and list content of top level directories in the `$APPLOCALDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/*"}]}},"scope-applocaldata-index":{"identifier":"scope-applocaldata-index","description":"This scope permits to list all files and folders in the `$APPLOCALDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"}]}},"scope-applocaldata-recursive":{"identifier":"scope-applocaldata-recursive","description":"This scope permits recursive access to the complete `$APPLOCALDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/**"}]}},"scope-applog":{"identifier":"scope-applog","description":"This scope permits access to all files and list content of top level directories in the `$APPLOG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"},{"path":"$APPLOG/*"}]}},"scope-applog-index":{"identifier":"scope-applog-index","description":"This scope permits to list all files and folders in the `$APPLOG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"}]}},"scope-applog-recursive":{"identifier":"scope-applog-recursive","description":"This scope permits recursive access to the complete `$APPLOG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"},{"path":"$APPLOG/**"}]}},"scope-audio":{"identifier":"scope-audio","description":"This scope permits access to all files and list content of top level directories in the `$AUDIO` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"},{"path":"$AUDIO/*"}]}},"scope-audio-index":{"identifier":"scope-audio-index","description":"This scope permits to list all files and folders in the `$AUDIO`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"}]}},"scope-audio-recursive":{"identifier":"scope-audio-recursive","description":"This scope permits recursive access to the complete `$AUDIO` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"},{"path":"$AUDIO/**"}]}},"scope-cache":{"identifier":"scope-cache","description":"This scope permits access to all files and list content of top level directories in the `$CACHE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"},{"path":"$CACHE/*"}]}},"scope-cache-index":{"identifier":"scope-cache-index","description":"This scope permits to list all files and folders in the `$CACHE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"}]}},"scope-cache-recursive":{"identifier":"scope-cache-recursive","description":"This scope permits recursive access to the complete `$CACHE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"},{"path":"$CACHE/**"}]}},"scope-config":{"identifier":"scope-config","description":"This scope permits access to all files and list content of top level directories in the `$CONFIG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"},{"path":"$CONFIG/*"}]}},"scope-config-index":{"identifier":"scope-config-index","description":"This scope permits to list all files and folders in the `$CONFIG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"}]}},"scope-config-recursive":{"identifier":"scope-config-recursive","description":"This scope permits recursive access to the complete `$CONFIG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"},{"path":"$CONFIG/**"}]}},"scope-data":{"identifier":"scope-data","description":"This scope permits access to all files and list content of top level directories in the `$DATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"},{"path":"$DATA/*"}]}},"scope-data-index":{"identifier":"scope-data-index","description":"This scope permits to list all files and folders in the `$DATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"}]}},"scope-data-recursive":{"identifier":"scope-data-recursive","description":"This scope permits recursive access to the complete `$DATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"},{"path":"$DATA/**"}]}},"scope-desktop":{"identifier":"scope-desktop","description":"This scope permits access to all files and list content of top level directories in the `$DESKTOP` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"},{"path":"$DESKTOP/*"}]}},"scope-desktop-index":{"identifier":"scope-desktop-index","description":"This scope permits to list all files and folders in the `$DESKTOP`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"}]}},"scope-desktop-recursive":{"identifier":"scope-desktop-recursive","description":"This scope permits recursive access to the complete `$DESKTOP` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"},{"path":"$DESKTOP/**"}]}},"scope-document":{"identifier":"scope-document","description":"This scope permits access to all files and list content of top level directories in the `$DOCUMENT` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"},{"path":"$DOCUMENT/*"}]}},"scope-document-index":{"identifier":"scope-document-index","description":"This scope permits to list all files and folders in the `$DOCUMENT`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"}]}},"scope-document-recursive":{"identifier":"scope-document-recursive","description":"This scope permits recursive access to the complete `$DOCUMENT` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"},{"path":"$DOCUMENT/**"}]}},"scope-download":{"identifier":"scope-download","description":"This scope permits access to all files and list content of top level directories in the `$DOWNLOAD` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"},{"path":"$DOWNLOAD/*"}]}},"scope-download-index":{"identifier":"scope-download-index","description":"This scope permits to list all files and folders in the `$DOWNLOAD`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"}]}},"scope-download-recursive":{"identifier":"scope-download-recursive","description":"This scope permits recursive access to the complete `$DOWNLOAD` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"},{"path":"$DOWNLOAD/**"}]}},"scope-exe":{"identifier":"scope-exe","description":"This scope permits access to all files and list content of top level directories in the `$EXE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"},{"path":"$EXE/*"}]}},"scope-exe-index":{"identifier":"scope-exe-index","description":"This scope permits to list all files and folders in the `$EXE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"}]}},"scope-exe-recursive":{"identifier":"scope-exe-recursive","description":"This scope permits recursive access to the complete `$EXE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"},{"path":"$EXE/**"}]}},"scope-font":{"identifier":"scope-font","description":"This scope permits access to all files and list content of top level directories in the `$FONT` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"},{"path":"$FONT/*"}]}},"scope-font-index":{"identifier":"scope-font-index","description":"This scope permits to list all files and folders in the `$FONT`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"}]}},"scope-font-recursive":{"identifier":"scope-font-recursive","description":"This scope permits recursive access to the complete `$FONT` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"},{"path":"$FONT/**"}]}},"scope-home":{"identifier":"scope-home","description":"This scope permits access to all files and list content of top level directories in the `$HOME` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"},{"path":"$HOME/*"}]}},"scope-home-index":{"identifier":"scope-home-index","description":"This scope permits to list all files and folders in the `$HOME`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"}]}},"scope-home-recursive":{"identifier":"scope-home-recursive","description":"This scope permits recursive access to the complete `$HOME` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"},{"path":"$HOME/**"}]}},"scope-localdata":{"identifier":"scope-localdata","description":"This scope permits access to all files and list content of top level directories in the `$LOCALDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"},{"path":"$LOCALDATA/*"}]}},"scope-localdata-index":{"identifier":"scope-localdata-index","description":"This scope permits to list all files and folders in the `$LOCALDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"}]}},"scope-localdata-recursive":{"identifier":"scope-localdata-recursive","description":"This scope permits recursive access to the complete `$LOCALDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"},{"path":"$LOCALDATA/**"}]}},"scope-log":{"identifier":"scope-log","description":"This scope permits access to all files and list content of top level directories in the `$LOG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"},{"path":"$LOG/*"}]}},"scope-log-index":{"identifier":"scope-log-index","description":"This scope permits to list all files and folders in the `$LOG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"}]}},"scope-log-recursive":{"identifier":"scope-log-recursive","description":"This scope permits recursive access to the complete `$LOG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"},{"path":"$LOG/**"}]}},"scope-picture":{"identifier":"scope-picture","description":"This scope permits access to all files and list content of top level directories in the `$PICTURE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"},{"path":"$PICTURE/*"}]}},"scope-picture-index":{"identifier":"scope-picture-index","description":"This scope permits to list all files and folders in the `$PICTURE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"}]}},"scope-picture-recursive":{"identifier":"scope-picture-recursive","description":"This scope permits recursive access to the complete `$PICTURE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"},{"path":"$PICTURE/**"}]}},"scope-public":{"identifier":"scope-public","description":"This scope permits access to all files and list content of top level directories in the `$PUBLIC` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"},{"path":"$PUBLIC/*"}]}},"scope-public-index":{"identifier":"scope-public-index","description":"This scope permits to list all files and folders in the `$PUBLIC`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"}]}},"scope-public-recursive":{"identifier":"scope-public-recursive","description":"This scope permits recursive access to the complete `$PUBLIC` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"},{"path":"$PUBLIC/**"}]}},"scope-resource":{"identifier":"scope-resource","description":"This scope permits access to all files and list content of top level directories in the `$RESOURCE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"},{"path":"$RESOURCE/*"}]}},"scope-resource-index":{"identifier":"scope-resource-index","description":"This scope permits to list all files and folders in the `$RESOURCE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"}]}},"scope-resource-recursive":{"identifier":"scope-resource-recursive","description":"This scope permits recursive access to the complete `$RESOURCE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"},{"path":"$RESOURCE/**"}]}},"scope-runtime":{"identifier":"scope-runtime","description":"This scope permits access to all files and list content of top level directories in the `$RUNTIME` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"},{"path":"$RUNTIME/*"}]}},"scope-runtime-index":{"identifier":"scope-runtime-index","description":"This scope permits to list all files and folders in the `$RUNTIME`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"}]}},"scope-runtime-recursive":{"identifier":"scope-runtime-recursive","description":"This scope permits recursive access to the complete `$RUNTIME` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"},{"path":"$RUNTIME/**"}]}},"scope-temp":{"identifier":"scope-temp","description":"This scope permits access to all files and list content of top level directories in the `$TEMP` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"},{"path":"$TEMP/*"}]}},"scope-temp-index":{"identifier":"scope-temp-index","description":"This scope permits to list all files and folders in the `$TEMP`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"}]}},"scope-temp-recursive":{"identifier":"scope-temp-recursive","description":"This scope permits recursive access to the complete `$TEMP` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"},{"path":"$TEMP/**"}]}},"scope-template":{"identifier":"scope-template","description":"This scope permits access to all files and list content of top level directories in the `$TEMPLATE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"},{"path":"$TEMPLATE/*"}]}},"scope-template-index":{"identifier":"scope-template-index","description":"This scope permits to list all files and folders in the `$TEMPLATE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"}]}},"scope-template-recursive":{"identifier":"scope-template-recursive","description":"This scope permits recursive access to the complete `$TEMPLATE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"},{"path":"$TEMPLATE/**"}]}},"scope-video":{"identifier":"scope-video","description":"This scope permits access to all files and list content of top level directories in the `$VIDEO` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"},{"path":"$VIDEO/*"}]}},"scope-video-index":{"identifier":"scope-video-index","description":"This scope permits to list all files and folders in the `$VIDEO`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"}]}},"scope-video-recursive":{"identifier":"scope-video-recursive","description":"This scope permits recursive access to the complete `$VIDEO` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"},{"path":"$VIDEO/**"}]}},"write-all":{"identifier":"write-all","description":"This enables all write related commands without any pre-configured accessible paths.","commands":{"allow":["mkdir","create","copy_file","remove","rename","truncate","ftruncate","write","write_file","write_text_file"],"deny":[]}},"write-files":{"identifier":"write-files","description":"This enables all file write related commands without any pre-configured accessible paths.","commands":{"allow":["create","copy_file","remove","rename","truncate","ftruncate","write","write_file","write_text_file"],"deny":[]}}},"permission_sets":{"allow-app-meta":{"identifier":"allow-app-meta","description":"This allows non-recursive read access to metadata of the application folders, including file listing and statistics.","permissions":["read-meta","scope-app-index"]},"allow-app-meta-recursive":{"identifier":"allow-app-meta-recursive","description":"This allows full recursive read access to metadata of the application folders, including file listing and statistics.","permissions":["read-meta","scope-app-recursive"]},"allow-app-read":{"identifier":"allow-app-read","description":"This allows non-recursive read access to the application folders.","permissions":["read-all","scope-app"]},"allow-app-read-recursive":{"identifier":"allow-app-read-recursive","description":"This allows full recursive read access to the complete application folders, files and subdirectories.","permissions":["read-all","scope-app-recursive"]},"allow-app-write":{"identifier":"allow-app-write","description":"This allows non-recursive write access to the application folders.","permissions":["write-all","scope-app"]},"allow-app-write-recursive":{"identifier":"allow-app-write-recursive","description":"This allows full recursive write access to the complete application folders, files and subdirectories.","permissions":["write-all","scope-app-recursive"]},"allow-appcache-meta":{"identifier":"allow-appcache-meta","description":"This allows non-recursive read access to metadata of the `$APPCACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-appcache-index"]},"allow-appcache-meta-recursive":{"identifier":"allow-appcache-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPCACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-appcache-recursive"]},"allow-appcache-read":{"identifier":"allow-appcache-read","description":"This allows non-recursive read access to the `$APPCACHE` folder.","permissions":["read-all","scope-appcache"]},"allow-appcache-read-recursive":{"identifier":"allow-appcache-read-recursive","description":"This allows full recursive read access to the complete `$APPCACHE` folder, files and subdirectories.","permissions":["read-all","scope-appcache-recursive"]},"allow-appcache-write":{"identifier":"allow-appcache-write","description":"This allows non-recursive write access to the `$APPCACHE` folder.","permissions":["write-all","scope-appcache"]},"allow-appcache-write-recursive":{"identifier":"allow-appcache-write-recursive","description":"This allows full recursive write access to the complete `$APPCACHE` folder, files and subdirectories.","permissions":["write-all","scope-appcache-recursive"]},"allow-appconfig-meta":{"identifier":"allow-appconfig-meta","description":"This allows non-recursive read access to metadata of the `$APPCONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-appconfig-index"]},"allow-appconfig-meta-recursive":{"identifier":"allow-appconfig-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPCONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-appconfig-recursive"]},"allow-appconfig-read":{"identifier":"allow-appconfig-read","description":"This allows non-recursive read access to the `$APPCONFIG` folder.","permissions":["read-all","scope-appconfig"]},"allow-appconfig-read-recursive":{"identifier":"allow-appconfig-read-recursive","description":"This allows full recursive read access to the complete `$APPCONFIG` folder, files and subdirectories.","permissions":["read-all","scope-appconfig-recursive"]},"allow-appconfig-write":{"identifier":"allow-appconfig-write","description":"This allows non-recursive write access to the `$APPCONFIG` folder.","permissions":["write-all","scope-appconfig"]},"allow-appconfig-write-recursive":{"identifier":"allow-appconfig-write-recursive","description":"This allows full recursive write access to the complete `$APPCONFIG` folder, files and subdirectories.","permissions":["write-all","scope-appconfig-recursive"]},"allow-appdata-meta":{"identifier":"allow-appdata-meta","description":"This allows non-recursive read access to metadata of the `$APPDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-appdata-index"]},"allow-appdata-meta-recursive":{"identifier":"allow-appdata-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-appdata-recursive"]},"allow-appdata-read":{"identifier":"allow-appdata-read","description":"This allows non-recursive read access to the `$APPDATA` folder.","permissions":["read-all","scope-appdata"]},"allow-appdata-read-recursive":{"identifier":"allow-appdata-read-recursive","description":"This allows full recursive read access to the complete `$APPDATA` folder, files and subdirectories.","permissions":["read-all","scope-appdata-recursive"]},"allow-appdata-write":{"identifier":"allow-appdata-write","description":"This allows non-recursive write access to the `$APPDATA` folder.","permissions":["write-all","scope-appdata"]},"allow-appdata-write-recursive":{"identifier":"allow-appdata-write-recursive","description":"This allows full recursive write access to the complete `$APPDATA` folder, files and subdirectories.","permissions":["write-all","scope-appdata-recursive"]},"allow-applocaldata-meta":{"identifier":"allow-applocaldata-meta","description":"This allows non-recursive read access to metadata of the `$APPLOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-applocaldata-index"]},"allow-applocaldata-meta-recursive":{"identifier":"allow-applocaldata-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPLOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-applocaldata-recursive"]},"allow-applocaldata-read":{"identifier":"allow-applocaldata-read","description":"This allows non-recursive read access to the `$APPLOCALDATA` folder.","permissions":["read-all","scope-applocaldata"]},"allow-applocaldata-read-recursive":{"identifier":"allow-applocaldata-read-recursive","description":"This allows full recursive read access to the complete `$APPLOCALDATA` folder, files and subdirectories.","permissions":["read-all","scope-applocaldata-recursive"]},"allow-applocaldata-write":{"identifier":"allow-applocaldata-write","description":"This allows non-recursive write access to the `$APPLOCALDATA` folder.","permissions":["write-all","scope-applocaldata"]},"allow-applocaldata-write-recursive":{"identifier":"allow-applocaldata-write-recursive","description":"This allows full recursive write access to the complete `$APPLOCALDATA` folder, files and subdirectories.","permissions":["write-all","scope-applocaldata-recursive"]},"allow-applog-meta":{"identifier":"allow-applog-meta","description":"This allows non-recursive read access to metadata of the `$APPLOG` folder, including file listing and statistics.","permissions":["read-meta","scope-applog-index"]},"allow-applog-meta-recursive":{"identifier":"allow-applog-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPLOG` folder, including file listing and statistics.","permissions":["read-meta","scope-applog-recursive"]},"allow-applog-read":{"identifier":"allow-applog-read","description":"This allows non-recursive read access to the `$APPLOG` folder.","permissions":["read-all","scope-applog"]},"allow-applog-read-recursive":{"identifier":"allow-applog-read-recursive","description":"This allows full recursive read access to the complete `$APPLOG` folder, files and subdirectories.","permissions":["read-all","scope-applog-recursive"]},"allow-applog-write":{"identifier":"allow-applog-write","description":"This allows non-recursive write access to the `$APPLOG` folder.","permissions":["write-all","scope-applog"]},"allow-applog-write-recursive":{"identifier":"allow-applog-write-recursive","description":"This allows full recursive write access to the complete `$APPLOG` folder, files and subdirectories.","permissions":["write-all","scope-applog-recursive"]},"allow-audio-meta":{"identifier":"allow-audio-meta","description":"This allows non-recursive read access to metadata of the `$AUDIO` folder, including file listing and statistics.","permissions":["read-meta","scope-audio-index"]},"allow-audio-meta-recursive":{"identifier":"allow-audio-meta-recursive","description":"This allows full recursive read access to metadata of the `$AUDIO` folder, including file listing and statistics.","permissions":["read-meta","scope-audio-recursive"]},"allow-audio-read":{"identifier":"allow-audio-read","description":"This allows non-recursive read access to the `$AUDIO` folder.","permissions":["read-all","scope-audio"]},"allow-audio-read-recursive":{"identifier":"allow-audio-read-recursive","description":"This allows full recursive read access to the complete `$AUDIO` folder, files and subdirectories.","permissions":["read-all","scope-audio-recursive"]},"allow-audio-write":{"identifier":"allow-audio-write","description":"This allows non-recursive write access to the `$AUDIO` folder.","permissions":["write-all","scope-audio"]},"allow-audio-write-recursive":{"identifier":"allow-audio-write-recursive","description":"This allows full recursive write access to the complete `$AUDIO` folder, files and subdirectories.","permissions":["write-all","scope-audio-recursive"]},"allow-cache-meta":{"identifier":"allow-cache-meta","description":"This allows non-recursive read access to metadata of the `$CACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-cache-index"]},"allow-cache-meta-recursive":{"identifier":"allow-cache-meta-recursive","description":"This allows full recursive read access to metadata of the `$CACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-cache-recursive"]},"allow-cache-read":{"identifier":"allow-cache-read","description":"This allows non-recursive read access to the `$CACHE` folder.","permissions":["read-all","scope-cache"]},"allow-cache-read-recursive":{"identifier":"allow-cache-read-recursive","description":"This allows full recursive read access to the complete `$CACHE` folder, files and subdirectories.","permissions":["read-all","scope-cache-recursive"]},"allow-cache-write":{"identifier":"allow-cache-write","description":"This allows non-recursive write access to the `$CACHE` folder.","permissions":["write-all","scope-cache"]},"allow-cache-write-recursive":{"identifier":"allow-cache-write-recursive","description":"This allows full recursive write access to the complete `$CACHE` folder, files and subdirectories.","permissions":["write-all","scope-cache-recursive"]},"allow-config-meta":{"identifier":"allow-config-meta","description":"This allows non-recursive read access to metadata of the `$CONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-config-index"]},"allow-config-meta-recursive":{"identifier":"allow-config-meta-recursive","description":"This allows full recursive read access to metadata of the `$CONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-config-recursive"]},"allow-config-read":{"identifier":"allow-config-read","description":"This allows non-recursive read access to the `$CONFIG` folder.","permissions":["read-all","scope-config"]},"allow-config-read-recursive":{"identifier":"allow-config-read-recursive","description":"This allows full recursive read access to the complete `$CONFIG` folder, files and subdirectories.","permissions":["read-all","scope-config-recursive"]},"allow-config-write":{"identifier":"allow-config-write","description":"This allows non-recursive write access to the `$CONFIG` folder.","permissions":["write-all","scope-config"]},"allow-config-write-recursive":{"identifier":"allow-config-write-recursive","description":"This allows full recursive write access to the complete `$CONFIG` folder, files and subdirectories.","permissions":["write-all","scope-config-recursive"]},"allow-data-meta":{"identifier":"allow-data-meta","description":"This allows non-recursive read access to metadata of the `$DATA` folder, including file listing and statistics.","permissions":["read-meta","scope-data-index"]},"allow-data-meta-recursive":{"identifier":"allow-data-meta-recursive","description":"This allows full recursive read access to metadata of the `$DATA` folder, including file listing and statistics.","permissions":["read-meta","scope-data-recursive"]},"allow-data-read":{"identifier":"allow-data-read","description":"This allows non-recursive read access to the `$DATA` folder.","permissions":["read-all","scope-data"]},"allow-data-read-recursive":{"identifier":"allow-data-read-recursive","description":"This allows full recursive read access to the complete `$DATA` folder, files and subdirectories.","permissions":["read-all","scope-data-recursive"]},"allow-data-write":{"identifier":"allow-data-write","description":"This allows non-recursive write access to the `$DATA` folder.","permissions":["write-all","scope-data"]},"allow-data-write-recursive":{"identifier":"allow-data-write-recursive","description":"This allows full recursive write access to the complete `$DATA` folder, files and subdirectories.","permissions":["write-all","scope-data-recursive"]},"allow-desktop-meta":{"identifier":"allow-desktop-meta","description":"This allows non-recursive read access to metadata of the `$DESKTOP` folder, including file listing and statistics.","permissions":["read-meta","scope-desktop-index"]},"allow-desktop-meta-recursive":{"identifier":"allow-desktop-meta-recursive","description":"This allows full recursive read access to metadata of the `$DESKTOP` folder, including file listing and statistics.","permissions":["read-meta","scope-desktop-recursive"]},"allow-desktop-read":{"identifier":"allow-desktop-read","description":"This allows non-recursive read access to the `$DESKTOP` folder.","permissions":["read-all","scope-desktop"]},"allow-desktop-read-recursive":{"identifier":"allow-desktop-read-recursive","description":"This allows full recursive read access to the complete `$DESKTOP` folder, files and subdirectories.","permissions":["read-all","scope-desktop-recursive"]},"allow-desktop-write":{"identifier":"allow-desktop-write","description":"This allows non-recursive write access to the `$DESKTOP` folder.","permissions":["write-all","scope-desktop"]},"allow-desktop-write-recursive":{"identifier":"allow-desktop-write-recursive","description":"This allows full recursive write access to the complete `$DESKTOP` folder, files and subdirectories.","permissions":["write-all","scope-desktop-recursive"]},"allow-document-meta":{"identifier":"allow-document-meta","description":"This allows non-recursive read access to metadata of the `$DOCUMENT` folder, including file listing and statistics.","permissions":["read-meta","scope-document-index"]},"allow-document-meta-recursive":{"identifier":"allow-document-meta-recursive","description":"This allows full recursive read access to metadata of the `$DOCUMENT` folder, including file listing and statistics.","permissions":["read-meta","scope-document-recursive"]},"allow-document-read":{"identifier":"allow-document-read","description":"This allows non-recursive read access to the `$DOCUMENT` folder.","permissions":["read-all","scope-document"]},"allow-document-read-recursive":{"identifier":"allow-document-read-recursive","description":"This allows full recursive read access to the complete `$DOCUMENT` folder, files and subdirectories.","permissions":["read-all","scope-document-recursive"]},"allow-document-write":{"identifier":"allow-document-write","description":"This allows non-recursive write access to the `$DOCUMENT` folder.","permissions":["write-all","scope-document"]},"allow-document-write-recursive":{"identifier":"allow-document-write-recursive","description":"This allows full recursive write access to the complete `$DOCUMENT` folder, files and subdirectories.","permissions":["write-all","scope-document-recursive"]},"allow-download-meta":{"identifier":"allow-download-meta","description":"This allows non-recursive read access to metadata of the `$DOWNLOAD` folder, including file listing and statistics.","permissions":["read-meta","scope-download-index"]},"allow-download-meta-recursive":{"identifier":"allow-download-meta-recursive","description":"This allows full recursive read access to metadata of the `$DOWNLOAD` folder, including file listing and statistics.","permissions":["read-meta","scope-download-recursive"]},"allow-download-read":{"identifier":"allow-download-read","description":"This allows non-recursive read access to the `$DOWNLOAD` folder.","permissions":["read-all","scope-download"]},"allow-download-read-recursive":{"identifier":"allow-download-read-recursive","description":"This allows full recursive read access to the complete `$DOWNLOAD` folder, files and subdirectories.","permissions":["read-all","scope-download-recursive"]},"allow-download-write":{"identifier":"allow-download-write","description":"This allows non-recursive write access to the `$DOWNLOAD` folder.","permissions":["write-all","scope-download"]},"allow-download-write-recursive":{"identifier":"allow-download-write-recursive","description":"This allows full recursive write access to the complete `$DOWNLOAD` folder, files and subdirectories.","permissions":["write-all","scope-download-recursive"]},"allow-exe-meta":{"identifier":"allow-exe-meta","description":"This allows non-recursive read access to metadata of the `$EXE` folder, including file listing and statistics.","permissions":["read-meta","scope-exe-index"]},"allow-exe-meta-recursive":{"identifier":"allow-exe-meta-recursive","description":"This allows full recursive read access to metadata of the `$EXE` folder, including file listing and statistics.","permissions":["read-meta","scope-exe-recursive"]},"allow-exe-read":{"identifier":"allow-exe-read","description":"This allows non-recursive read access to the `$EXE` folder.","permissions":["read-all","scope-exe"]},"allow-exe-read-recursive":{"identifier":"allow-exe-read-recursive","description":"This allows full recursive read access to the complete `$EXE` folder, files and subdirectories.","permissions":["read-all","scope-exe-recursive"]},"allow-exe-write":{"identifier":"allow-exe-write","description":"This allows non-recursive write access to the `$EXE` folder.","permissions":["write-all","scope-exe"]},"allow-exe-write-recursive":{"identifier":"allow-exe-write-recursive","description":"This allows full recursive write access to the complete `$EXE` folder, files and subdirectories.","permissions":["write-all","scope-exe-recursive"]},"allow-font-meta":{"identifier":"allow-font-meta","description":"This allows non-recursive read access to metadata of the `$FONT` folder, including file listing and statistics.","permissions":["read-meta","scope-font-index"]},"allow-font-meta-recursive":{"identifier":"allow-font-meta-recursive","description":"This allows full recursive read access to metadata of the `$FONT` folder, including file listing and statistics.","permissions":["read-meta","scope-font-recursive"]},"allow-font-read":{"identifier":"allow-font-read","description":"This allows non-recursive read access to the `$FONT` folder.","permissions":["read-all","scope-font"]},"allow-font-read-recursive":{"identifier":"allow-font-read-recursive","description":"This allows full recursive read access to the complete `$FONT` folder, files and subdirectories.","permissions":["read-all","scope-font-recursive"]},"allow-font-write":{"identifier":"allow-font-write","description":"This allows non-recursive write access to the `$FONT` folder.","permissions":["write-all","scope-font"]},"allow-font-write-recursive":{"identifier":"allow-font-write-recursive","description":"This allows full recursive write access to the complete `$FONT` folder, files and subdirectories.","permissions":["write-all","scope-font-recursive"]},"allow-home-meta":{"identifier":"allow-home-meta","description":"This allows non-recursive read access to metadata of the `$HOME` folder, including file listing and statistics.","permissions":["read-meta","scope-home-index"]},"allow-home-meta-recursive":{"identifier":"allow-home-meta-recursive","description":"This allows full recursive read access to metadata of the `$HOME` folder, including file listing and statistics.","permissions":["read-meta","scope-home-recursive"]},"allow-home-read":{"identifier":"allow-home-read","description":"This allows non-recursive read access to the `$HOME` folder.","permissions":["read-all","scope-home"]},"allow-home-read-recursive":{"identifier":"allow-home-read-recursive","description":"This allows full recursive read access to the complete `$HOME` folder, files and subdirectories.","permissions":["read-all","scope-home-recursive"]},"allow-home-write":{"identifier":"allow-home-write","description":"This allows non-recursive write access to the `$HOME` folder.","permissions":["write-all","scope-home"]},"allow-home-write-recursive":{"identifier":"allow-home-write-recursive","description":"This allows full recursive write access to the complete `$HOME` folder, files and subdirectories.","permissions":["write-all","scope-home-recursive"]},"allow-localdata-meta":{"identifier":"allow-localdata-meta","description":"This allows non-recursive read access to metadata of the `$LOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-localdata-index"]},"allow-localdata-meta-recursive":{"identifier":"allow-localdata-meta-recursive","description":"This allows full recursive read access to metadata of the `$LOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-localdata-recursive"]},"allow-localdata-read":{"identifier":"allow-localdata-read","description":"This allows non-recursive read access to the `$LOCALDATA` folder.","permissions":["read-all","scope-localdata"]},"allow-localdata-read-recursive":{"identifier":"allow-localdata-read-recursive","description":"This allows full recursive read access to the complete `$LOCALDATA` folder, files and subdirectories.","permissions":["read-all","scope-localdata-recursive"]},"allow-localdata-write":{"identifier":"allow-localdata-write","description":"This allows non-recursive write access to the `$LOCALDATA` folder.","permissions":["write-all","scope-localdata"]},"allow-localdata-write-recursive":{"identifier":"allow-localdata-write-recursive","description":"This allows full recursive write access to the complete `$LOCALDATA` folder, files and subdirectories.","permissions":["write-all","scope-localdata-recursive"]},"allow-log-meta":{"identifier":"allow-log-meta","description":"This allows non-recursive read access to metadata of the `$LOG` folder, including file listing and statistics.","permissions":["read-meta","scope-log-index"]},"allow-log-meta-recursive":{"identifier":"allow-log-meta-recursive","description":"This allows full recursive read access to metadata of the `$LOG` folder, including file listing and statistics.","permissions":["read-meta","scope-log-recursive"]},"allow-log-read":{"identifier":"allow-log-read","description":"This allows non-recursive read access to the `$LOG` folder.","permissions":["read-all","scope-log"]},"allow-log-read-recursive":{"identifier":"allow-log-read-recursive","description":"This allows full recursive read access to the complete `$LOG` folder, files and subdirectories.","permissions":["read-all","scope-log-recursive"]},"allow-log-write":{"identifier":"allow-log-write","description":"This allows non-recursive write access to the `$LOG` folder.","permissions":["write-all","scope-log"]},"allow-log-write-recursive":{"identifier":"allow-log-write-recursive","description":"This allows full recursive write access to the complete `$LOG` folder, files and subdirectories.","permissions":["write-all","scope-log-recursive"]},"allow-picture-meta":{"identifier":"allow-picture-meta","description":"This allows non-recursive read access to metadata of the `$PICTURE` folder, including file listing and statistics.","permissions":["read-meta","scope-picture-index"]},"allow-picture-meta-recursive":{"identifier":"allow-picture-meta-recursive","description":"This allows full recursive read access to metadata of the `$PICTURE` folder, including file listing and statistics.","permissions":["read-meta","scope-picture-recursive"]},"allow-picture-read":{"identifier":"allow-picture-read","description":"This allows non-recursive read access to the `$PICTURE` folder.","permissions":["read-all","scope-picture"]},"allow-picture-read-recursive":{"identifier":"allow-picture-read-recursive","description":"This allows full recursive read access to the complete `$PICTURE` folder, files and subdirectories.","permissions":["read-all","scope-picture-recursive"]},"allow-picture-write":{"identifier":"allow-picture-write","description":"This allows non-recursive write access to the `$PICTURE` folder.","permissions":["write-all","scope-picture"]},"allow-picture-write-recursive":{"identifier":"allow-picture-write-recursive","description":"This allows full recursive write access to the complete `$PICTURE` folder, files and subdirectories.","permissions":["write-all","scope-picture-recursive"]},"allow-public-meta":{"identifier":"allow-public-meta","description":"This allows non-recursive read access to metadata of the `$PUBLIC` folder, including file listing and statistics.","permissions":["read-meta","scope-public-index"]},"allow-public-meta-recursive":{"identifier":"allow-public-meta-recursive","description":"This allows full recursive read access to metadata of the `$PUBLIC` folder, including file listing and statistics.","permissions":["read-meta","scope-public-recursive"]},"allow-public-read":{"identifier":"allow-public-read","description":"This allows non-recursive read access to the `$PUBLIC` folder.","permissions":["read-all","scope-public"]},"allow-public-read-recursive":{"identifier":"allow-public-read-recursive","description":"This allows full recursive read access to the complete `$PUBLIC` folder, files and subdirectories.","permissions":["read-all","scope-public-recursive"]},"allow-public-write":{"identifier":"allow-public-write","description":"This allows non-recursive write access to the `$PUBLIC` folder.","permissions":["write-all","scope-public"]},"allow-public-write-recursive":{"identifier":"allow-public-write-recursive","description":"This allows full recursive write access to the complete `$PUBLIC` folder, files and subdirectories.","permissions":["write-all","scope-public-recursive"]},"allow-resource-meta":{"identifier":"allow-resource-meta","description":"This allows non-recursive read access to metadata of the `$RESOURCE` folder, including file listing and statistics.","permissions":["read-meta","scope-resource-index"]},"allow-resource-meta-recursive":{"identifier":"allow-resource-meta-recursive","description":"This allows full recursive read access to metadata of the `$RESOURCE` folder, including file listing and statistics.","permissions":["read-meta","scope-resource-recursive"]},"allow-resource-read":{"identifier":"allow-resource-read","description":"This allows non-recursive read access to the `$RESOURCE` folder.","permissions":["read-all","scope-resource"]},"allow-resource-read-recursive":{"identifier":"allow-resource-read-recursive","description":"This allows full recursive read access to the complete `$RESOURCE` folder, files and subdirectories.","permissions":["read-all","scope-resource-recursive"]},"allow-resource-write":{"identifier":"allow-resource-write","description":"This allows non-recursive write access to the `$RESOURCE` folder.","permissions":["write-all","scope-resource"]},"allow-resource-write-recursive":{"identifier":"allow-resource-write-recursive","description":"This allows full recursive write access to the complete `$RESOURCE` folder, files and subdirectories.","permissions":["write-all","scope-resource-recursive"]},"allow-runtime-meta":{"identifier":"allow-runtime-meta","description":"This allows non-recursive read access to metadata of the `$RUNTIME` folder, including file listing and statistics.","permissions":["read-meta","scope-runtime-index"]},"allow-runtime-meta-recursive":{"identifier":"allow-runtime-meta-recursive","description":"This allows full recursive read access to metadata of the `$RUNTIME` folder, including file listing and statistics.","permissions":["read-meta","scope-runtime-recursive"]},"allow-runtime-read":{"identifier":"allow-runtime-read","description":"This allows non-recursive read access to the `$RUNTIME` folder.","permissions":["read-all","scope-runtime"]},"allow-runtime-read-recursive":{"identifier":"allow-runtime-read-recursive","description":"This allows full recursive read access to the complete `$RUNTIME` folder, files and subdirectories.","permissions":["read-all","scope-runtime-recursive"]},"allow-runtime-write":{"identifier":"allow-runtime-write","description":"This allows non-recursive write access to the `$RUNTIME` folder.","permissions":["write-all","scope-runtime"]},"allow-runtime-write-recursive":{"identifier":"allow-runtime-write-recursive","description":"This allows full recursive write access to the complete `$RUNTIME` folder, files and subdirectories.","permissions":["write-all","scope-runtime-recursive"]},"allow-temp-meta":{"identifier":"allow-temp-meta","description":"This allows non-recursive read access to metadata of the `$TEMP` folder, including file listing and statistics.","permissions":["read-meta","scope-temp-index"]},"allow-temp-meta-recursive":{"identifier":"allow-temp-meta-recursive","description":"This allows full recursive read access to metadata of the `$TEMP` folder, including file listing and statistics.","permissions":["read-meta","scope-temp-recursive"]},"allow-temp-read":{"identifier":"allow-temp-read","description":"This allows non-recursive read access to the `$TEMP` folder.","permissions":["read-all","scope-temp"]},"allow-temp-read-recursive":{"identifier":"allow-temp-read-recursive","description":"This allows full recursive read access to the complete `$TEMP` folder, files and subdirectories.","permissions":["read-all","scope-temp-recursive"]},"allow-temp-write":{"identifier":"allow-temp-write","description":"This allows non-recursive write access to the `$TEMP` folder.","permissions":["write-all","scope-temp"]},"allow-temp-write-recursive":{"identifier":"allow-temp-write-recursive","description":"This allows full recursive write access to the complete `$TEMP` folder, files and subdirectories.","permissions":["write-all","scope-temp-recursive"]},"allow-template-meta":{"identifier":"allow-template-meta","description":"This allows non-recursive read access to metadata of the `$TEMPLATE` folder, including file listing and statistics.","permissions":["read-meta","scope-template-index"]},"allow-template-meta-recursive":{"identifier":"allow-template-meta-recursive","description":"This allows full recursive read access to metadata of the `$TEMPLATE` folder, including file listing and statistics.","permissions":["read-meta","scope-template-recursive"]},"allow-template-read":{"identifier":"allow-template-read","description":"This allows non-recursive read access to the `$TEMPLATE` folder.","permissions":["read-all","scope-template"]},"allow-template-read-recursive":{"identifier":"allow-template-read-recursive","description":"This allows full recursive read access to the complete `$TEMPLATE` folder, files and subdirectories.","permissions":["read-all","scope-template-recursive"]},"allow-template-write":{"identifier":"allow-template-write","description":"This allows non-recursive write access to the `$TEMPLATE` folder.","permissions":["write-all","scope-template"]},"allow-template-write-recursive":{"identifier":"allow-template-write-recursive","description":"This allows full recursive write access to the complete `$TEMPLATE` folder, files and subdirectories.","permissions":["write-all","scope-template-recursive"]},"allow-video-meta":{"identifier":"allow-video-meta","description":"This allows non-recursive read access to metadata of the `$VIDEO` folder, including file listing and statistics.","permissions":["read-meta","scope-video-index"]},"allow-video-meta-recursive":{"identifier":"allow-video-meta-recursive","description":"This allows full recursive read access to metadata of the `$VIDEO` folder, including file listing and statistics.","permissions":["read-meta","scope-video-recursive"]},"allow-video-read":{"identifier":"allow-video-read","description":"This allows non-recursive read access to the `$VIDEO` folder.","permissions":["read-all","scope-video"]},"allow-video-read-recursive":{"identifier":"allow-video-read-recursive","description":"This allows full recursive read access to the complete `$VIDEO` folder, files and subdirectories.","permissions":["read-all","scope-video-recursive"]},"allow-video-write":{"identifier":"allow-video-write","description":"This allows non-recursive write access to the `$VIDEO` folder.","permissions":["write-all","scope-video"]},"allow-video-write-recursive":{"identifier":"allow-video-write-recursive","description":"This allows full recursive write access to the complete `$VIDEO` folder, files and subdirectories.","permissions":["write-all","scope-video-recursive"]},"deny-default":{"identifier":"deny-default","description":"This denies access to dangerous Tauri relevant files and folders by default.","permissions":["deny-webview-data-linux","deny-webview-data-windows"]}},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"description":"A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},{"properties":{"path":{"description":"A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"description":"FS scope entry.","title":"FsScopeEntry"}},"log":{"default_permission":{"identifier":"default","description":"Allows the log command","permissions":["allow-log"]},"permissions":{"allow-log":{"identifier":"allow-log","description":"Enables the log command without any pre-configured scope.","commands":{"allow":["log"],"deny":[]}},"deny-log":{"identifier":"deny-log","description":"Denies the log command without any pre-configured scope.","commands":{"allow":[],"deny":["log"]}}},"permission_sets":{},"global_scope_schema":null},"opener":{"default_permission":{"identifier":"default","description":"This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer","permissions":["allow-open-url","allow-reveal-item-in-dir","allow-default-urls"]},"permissions":{"allow-default-urls":{"identifier":"allow-default-urls","description":"This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"url":"mailto:*"},{"url":"tel:*"},{"url":"http://*"},{"url":"https://*"}]}},"allow-open-path":{"identifier":"allow-open-path","description":"Enables the open_path command without any pre-configured scope.","commands":{"allow":["open_path"],"deny":[]}},"allow-open-url":{"identifier":"allow-open-url","description":"Enables the open_url command without any pre-configured scope.","commands":{"allow":["open_url"],"deny":[]}},"allow-reveal-item-in-dir":{"identifier":"allow-reveal-item-in-dir","description":"Enables the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":["reveal_item_in_dir"],"deny":[]}},"deny-open-path":{"identifier":"deny-open-path","description":"Denies the open_path command without any pre-configured scope.","commands":{"allow":[],"deny":["open_path"]}},"deny-open-url":{"identifier":"deny-open-url","description":"Denies the open_url command without any pre-configured scope.","commands":{"allow":[],"deny":["open_url"]}},"deny-reveal-item-in-dir":{"identifier":"deny-reveal-item-in-dir","description":"Denies the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["reveal_item_in_dir"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this url with, for example: firefox."},"url":{"description":"A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.amrom.workers.dev/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"","type":"string"}},"required":["url"],"type":"object"},{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this path with, for example: xdg-open."},"path":{"description":"A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"definitions":{"Application":{"anyOf":[{"description":"Open in default application.","type":"null"},{"description":"If true, allow open with any application.","type":"boolean"},{"description":"Allow specific application to open with.","type":"string"}],"description":"Opener scope application."}},"description":"Opener scope entry.","title":"OpenerScopeEntry"}},"os":{"default_permission":{"identifier":"default","description":"This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n","permissions":["allow-arch","allow-exe-extension","allow-family","allow-locale","allow-os-type","allow-platform","allow-version"]},"permissions":{"allow-arch":{"identifier":"allow-arch","description":"Enables the arch command without any pre-configured scope.","commands":{"allow":["arch"],"deny":[]}},"allow-exe-extension":{"identifier":"allow-exe-extension","description":"Enables the exe_extension command without any pre-configured scope.","commands":{"allow":["exe_extension"],"deny":[]}},"allow-family":{"identifier":"allow-family","description":"Enables the family command without any pre-configured scope.","commands":{"allow":["family"],"deny":[]}},"allow-hostname":{"identifier":"allow-hostname","description":"Enables the hostname command without any pre-configured scope.","commands":{"allow":["hostname"],"deny":[]}},"allow-locale":{"identifier":"allow-locale","description":"Enables the locale command without any pre-configured scope.","commands":{"allow":["locale"],"deny":[]}},"allow-os-type":{"identifier":"allow-os-type","description":"Enables the os_type command without any pre-configured scope.","commands":{"allow":["os_type"],"deny":[]}},"allow-platform":{"identifier":"allow-platform","description":"Enables the platform command without any pre-configured scope.","commands":{"allow":["platform"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-arch":{"identifier":"deny-arch","description":"Denies the arch command without any pre-configured scope.","commands":{"allow":[],"deny":["arch"]}},"deny-exe-extension":{"identifier":"deny-exe-extension","description":"Denies the exe_extension command without any pre-configured scope.","commands":{"allow":[],"deny":["exe_extension"]}},"deny-family":{"identifier":"deny-family","description":"Denies the family command without any pre-configured scope.","commands":{"allow":[],"deny":["family"]}},"deny-hostname":{"identifier":"deny-hostname","description":"Denies the hostname command without any pre-configured scope.","commands":{"allow":[],"deny":["hostname"]}},"deny-locale":{"identifier":"deny-locale","description":"Denies the locale command without any pre-configured scope.","commands":{"allow":[],"deny":["locale"]}},"deny-os-type":{"identifier":"deny-os-type","description":"Denies the os_type command without any pre-configured scope.","commands":{"allow":[],"deny":["os_type"]}},"deny-platform":{"identifier":"deny-platform","description":"Denies the platform command without any pre-configured scope.","commands":{"allow":[],"deny":["platform"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"}},"required":["cmd","name"],"type":"object"},{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["name","sidecar"],"type":"object"}],"definitions":{"ShellScopeEntryAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"raw":{"default":false,"description":"Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.","type":"boolean"},"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellScopeEntryAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellScopeEntryAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"Shell scope entry.","title":"ShellScopeEntry"}},"updater":{"default_permission":{"identifier":"default","description":"This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n","permissions":["allow-check","allow-download","allow-install","allow-download-and-install"]},"permissions":{"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"allow-download":{"identifier":"allow-download","description":"Enables the download command without any pre-configured scope.","commands":{"allow":["download"],"deny":[]}},"allow-download-and-install":{"identifier":"allow-download-and-install","description":"Enables the download_and_install command without any pre-configured scope.","commands":{"allow":["download_and_install"],"deny":[]}},"allow-install":{"identifier":"allow-install","description":"Enables the install command without any pre-configured scope.","commands":{"allow":["install"],"deny":[]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}},"deny-download":{"identifier":"deny-download","description":"Denies the download command without any pre-configured scope.","commands":{"allow":[],"deny":["download"]}},"deny-download-and-install":{"identifier":"deny-download-and-install","description":"Denies the download_and_install command without any pre-configured scope.","commands":{"allow":[],"deny":["download_and_install"]}},"deny-install":{"identifier":"deny-install","description":"Denies the install command without any pre-configured scope.","commands":{"allow":[],"deny":["install"]}}},"permission_sets":{},"global_scope_schema":null},"window-state":{"default_permission":{"identifier":"default","description":"This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n","permissions":["allow-filename","allow-restore-state","allow-save-window-state"]},"permissions":{"allow-filename":{"identifier":"allow-filename","description":"Enables the filename command without any pre-configured scope.","commands":{"allow":["filename"],"deny":[]}},"allow-restore-state":{"identifier":"allow-restore-state","description":"Enables the restore_state command without any pre-configured scope.","commands":{"allow":["restore_state"],"deny":[]}},"allow-save-window-state":{"identifier":"allow-save-window-state","description":"Enables the save_window_state command without any pre-configured scope.","commands":{"allow":["save_window_state"],"deny":[]}},"deny-filename":{"identifier":"deny-filename","description":"Denies the filename command without any pre-configured scope.","commands":{"allow":[],"deny":["filename"]}},"deny-restore-state":{"identifier":"deny-restore-state","description":"Denies the restore_state command without any pre-configured scope.","commands":{"allow":[],"deny":["restore_state"]}},"deny-save-window-state":{"identifier":"deny-save-window-state","description":"Denies the save_window_state command without any pre-configured scope.","commands":{"allow":[],"deny":["save_window_state"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-git":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-add","allow-branch","allow-checkout","allow-commit","allow-delete-branch","allow-fetch-all","allow-initialize","allow-log","allow-merge-branch","allow-pull","allow-push","allow-status","allow-unstage"]},"permissions":{"allow-add":{"identifier":"allow-add","description":"Enables the add command without any pre-configured scope.","commands":{"allow":["add"],"deny":[]}},"allow-branch":{"identifier":"allow-branch","description":"Enables the branch command without any pre-configured scope.","commands":{"allow":["branch"],"deny":[]}},"allow-checkout":{"identifier":"allow-checkout","description":"Enables the checkout command without any pre-configured scope.","commands":{"allow":["checkout"],"deny":[]}},"allow-checkout-remote":{"identifier":"allow-checkout-remote","description":"Enables the checkout_remote command without any pre-configured scope.","commands":{"allow":["checkout_remote"],"deny":[]}},"allow-commit":{"identifier":"allow-commit","description":"Enables the commit command without any pre-configured scope.","commands":{"allow":["commit"],"deny":[]}},"allow-delete-branch":{"identifier":"allow-delete-branch","description":"Enables the delete_branch command without any pre-configured scope.","commands":{"allow":["delete_branch"],"deny":[]}},"allow-fetch-all":{"identifier":"allow-fetch-all","description":"Enables the fetch_all command without any pre-configured scope.","commands":{"allow":["fetch_all"],"deny":[]}},"allow-initialize":{"identifier":"allow-initialize","description":"Enables the initialize command without any pre-configured scope.","commands":{"allow":["initialize"],"deny":[]}},"allow-log":{"identifier":"allow-log","description":"Enables the log command without any pre-configured scope.","commands":{"allow":["log"],"deny":[]}},"allow-merge-branch":{"identifier":"allow-merge-branch","description":"Enables the merge_branch command without any pre-configured scope.","commands":{"allow":["merge_branch"],"deny":[]}},"allow-pull":{"identifier":"allow-pull","description":"Enables the pull command without any pre-configured scope.","commands":{"allow":["pull"],"deny":[]}},"allow-push":{"identifier":"allow-push","description":"Enables the push command without any pre-configured scope.","commands":{"allow":["push"],"deny":[]}},"allow-status":{"identifier":"allow-status","description":"Enables the status command without any pre-configured scope.","commands":{"allow":["status"],"deny":[]}},"allow-unstage":{"identifier":"allow-unstage","description":"Enables the unstage command without any pre-configured scope.","commands":{"allow":["unstage"],"deny":[]}},"deny-add":{"identifier":"deny-add","description":"Denies the add command without any pre-configured scope.","commands":{"allow":[],"deny":["add"]}},"deny-branch":{"identifier":"deny-branch","description":"Denies the branch command without any pre-configured scope.","commands":{"allow":[],"deny":["branch"]}},"deny-checkout":{"identifier":"deny-checkout","description":"Denies the checkout command without any pre-configured scope.","commands":{"allow":[],"deny":["checkout"]}},"deny-checkout-remote":{"identifier":"deny-checkout-remote","description":"Denies the checkout_remote command without any pre-configured scope.","commands":{"allow":[],"deny":["checkout_remote"]}},"deny-commit":{"identifier":"deny-commit","description":"Denies the commit command without any pre-configured scope.","commands":{"allow":[],"deny":["commit"]}},"deny-delete-branch":{"identifier":"deny-delete-branch","description":"Denies the delete_branch command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_branch"]}},"deny-fetch-all":{"identifier":"deny-fetch-all","description":"Denies the fetch_all command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_all"]}},"deny-initialize":{"identifier":"deny-initialize","description":"Denies the initialize command without any pre-configured scope.","commands":{"allow":[],"deny":["initialize"]}},"deny-log":{"identifier":"deny-log","description":"Denies the log command without any pre-configured scope.","commands":{"allow":[],"deny":["log"]}},"deny-merge-branch":{"identifier":"deny-merge-branch","description":"Denies the merge_branch command without any pre-configured scope.","commands":{"allow":[],"deny":["merge_branch"]}},"deny-pull":{"identifier":"deny-pull","description":"Denies the pull command without any pre-configured scope.","commands":{"allow":[],"deny":["pull"]}},"deny-push":{"identifier":"deny-push","description":"Denies the push command without any pre-configured scope.","commands":{"allow":[],"deny":["push"]}},"deny-status":{"identifier":"deny-status","description":"Denies the status command without any pre-configured scope.","commands":{"allow":[],"deny":["status"]}},"deny-unstage":{"identifier":"deny-unstage","description":"Denies the unstage command without any pre-configured scope.","commands":{"allow":[],"deny":["unstage"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-license":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-check","allow-activate","allow-deactivate"]},"permissions":{"allow-activate":{"identifier":"allow-activate","description":"Enables the activate command without any pre-configured scope.","commands":{"allow":["activate"],"deny":[]}},"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"allow-deactivate":{"identifier":"allow-deactivate","description":"Enables the deactivate command without any pre-configured scope.","commands":{"allow":["deactivate"],"deny":[]}},"deny-activate":{"identifier":"deny-activate","description":"Denies the activate command without any pre-configured scope.","commands":{"allow":[],"deny":["activate"]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}},"deny-deactivate":{"identifier":"deny-deactivate","description":"Denies the deactivate command without any pre-configured scope.","commands":{"allow":[],"deny":["deactivate"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-models":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-upsert","allow-delete"]},"permissions":{"allow-delete":{"identifier":"allow-delete","description":"Enables the delete command without any pre-configured scope.","commands":{"allow":["delete"],"deny":[]}},"allow-delete-model":{"identifier":"allow-delete-model","description":"Enables the delete_model command without any pre-configured scope.","commands":{"allow":["delete_model"],"deny":[]}},"allow-upsert":{"identifier":"allow-upsert","description":"Enables the upsert command without any pre-configured scope.","commands":{"allow":["upsert"],"deny":[]}},"allow-upsert-model":{"identifier":"allow-upsert-model","description":"Enables the upsert_model command without any pre-configured scope.","commands":{"allow":["upsert_model"],"deny":[]}},"deny-delete":{"identifier":"deny-delete","description":"Denies the delete command without any pre-configured scope.","commands":{"allow":[],"deny":["delete"]}},"deny-delete-model":{"identifier":"deny-delete-model","description":"Denies the delete_model command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_model"]}},"deny-upsert":{"identifier":"deny-upsert","description":"Denies the upsert command without any pre-configured scope.","commands":{"allow":[],"deny":["upsert"]}},"deny-upsert-model":{"identifier":"deny-upsert-model","description":"Denies the upsert_model command without any pre-configured scope.","commands":{"allow":[],"deny":["upsert_model"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-sync":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-calculate","allow-calculate-fs","allow-apply","allow-watch"]},"permissions":{"allow-apply":{"identifier":"allow-apply","description":"Enables the apply command without any pre-configured scope.","commands":{"allow":["apply"],"deny":[]}},"allow-calculate":{"identifier":"allow-calculate","description":"Enables the calculate command without any pre-configured scope.","commands":{"allow":["calculate"],"deny":[]}},"allow-calculate-fs":{"identifier":"allow-calculate-fs","description":"Enables the calculate_fs command without any pre-configured scope.","commands":{"allow":["calculate_fs"],"deny":[]}},"allow-watch":{"identifier":"allow-watch","description":"Enables the watch command without any pre-configured scope.","commands":{"allow":["watch"],"deny":[]}},"deny-apply":{"identifier":"deny-apply","description":"Denies the apply command without any pre-configured scope.","commands":{"allow":[],"deny":["apply"]}},"deny-calculate":{"identifier":"deny-calculate","description":"Denies the calculate command without any pre-configured scope.","commands":{"allow":[],"deny":["calculate"]}},"deny-calculate-fs":{"identifier":"deny-calculate-fs","description":"Denies the calculate_fs command without any pre-configured scope.","commands":{"allow":[],"deny":["calculate_fs"]}},"deny-watch":{"identifier":"deny-watch","description":"Denies the watch command without any pre-configured scope.","commands":{"allow":[],"deny":["watch"]}}},"permission_sets":{},"global_scope_schema":null},"yaak-ws":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin","permissions":["allow-close","allow-connect","allow-delete-connection","allow-delete-connections","allow-delete-request","allow-duplicate-request","allow-list-connections","allow-list-events","allow-list-requests","allow-send","allow-upsert-request"]},"permissions":{"allow-cancel":{"identifier":"allow-cancel","description":"Enables the cancel command without any pre-configured scope.","commands":{"allow":["cancel"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-connect":{"identifier":"allow-connect","description":"Enables the connect command without any pre-configured scope.","commands":{"allow":["connect"],"deny":[]}},"allow-delete-connection":{"identifier":"allow-delete-connection","description":"Enables the delete_connection command without any pre-configured scope.","commands":{"allow":["delete_connection"],"deny":[]}},"allow-delete-connections":{"identifier":"allow-delete-connections","description":"Enables the delete_connections command without any pre-configured scope.","commands":{"allow":["delete_connections"],"deny":[]}},"allow-delete-request":{"identifier":"allow-delete-request","description":"Enables the delete_request command without any pre-configured scope.","commands":{"allow":["delete_request"],"deny":[]}},"allow-duplicate-request":{"identifier":"allow-duplicate-request","description":"Enables the duplicate_request command without any pre-configured scope.","commands":{"allow":["duplicate_request"],"deny":[]}},"allow-list-connections":{"identifier":"allow-list-connections","description":"Enables the list_connections command without any pre-configured scope.","commands":{"allow":["list_connections"],"deny":[]}},"allow-list-events":{"identifier":"allow-list-events","description":"Enables the list_events command without any pre-configured scope.","commands":{"allow":["list_events"],"deny":[]}},"allow-list-requests":{"identifier":"allow-list-requests","description":"Enables the list_requests command without any pre-configured scope.","commands":{"allow":["list_requests"],"deny":[]}},"allow-list-websocket-connections":{"identifier":"allow-list-websocket-connections","description":"Enables the list_websocket_connections command without any pre-configured scope.","commands":{"allow":["list_websocket_connections"],"deny":[]}},"allow-list-websocket-requests":{"identifier":"allow-list-websocket-requests","description":"Enables the list_websocket_requests command without any pre-configured scope.","commands":{"allow":["list_websocket_requests"],"deny":[]}},"allow-send":{"identifier":"allow-send","description":"Enables the send command without any pre-configured scope.","commands":{"allow":["send"],"deny":[]}},"allow-upsert-request":{"identifier":"allow-upsert-request","description":"Enables the upsert_request command without any pre-configured scope.","commands":{"allow":["upsert_request"],"deny":[]}},"allow-upsert-websocket-request":{"identifier":"allow-upsert-websocket-request","description":"Enables the upsert_websocket_request command without any pre-configured scope.","commands":{"allow":["upsert_websocket_request"],"deny":[]}},"deny-cancel":{"identifier":"deny-cancel","description":"Denies the cancel command without any pre-configured scope.","commands":{"allow":[],"deny":["cancel"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-connect":{"identifier":"deny-connect","description":"Denies the connect command without any pre-configured scope.","commands":{"allow":[],"deny":["connect"]}},"deny-delete-connection":{"identifier":"deny-delete-connection","description":"Denies the delete_connection command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_connection"]}},"deny-delete-connections":{"identifier":"deny-delete-connections","description":"Denies the delete_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_connections"]}},"deny-delete-request":{"identifier":"deny-delete-request","description":"Denies the delete_request command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_request"]}},"deny-duplicate-request":{"identifier":"deny-duplicate-request","description":"Denies the duplicate_request command without any pre-configured scope.","commands":{"allow":[],"deny":["duplicate_request"]}},"deny-list-connections":{"identifier":"deny-list-connections","description":"Denies the list_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["list_connections"]}},"deny-list-events":{"identifier":"deny-list-events","description":"Denies the list_events command without any pre-configured scope.","commands":{"allow":[],"deny":["list_events"]}},"deny-list-requests":{"identifier":"deny-list-requests","description":"Denies the list_requests command without any pre-configured scope.","commands":{"allow":[],"deny":["list_requests"]}},"deny-list-websocket-connections":{"identifier":"deny-list-websocket-connections","description":"Denies the list_websocket_connections command without any pre-configured scope.","commands":{"allow":[],"deny":["list_websocket_connections"]}},"deny-list-websocket-requests":{"identifier":"deny-list-websocket-requests","description":"Denies the list_websocket_requests command without any pre-configured scope.","commands":{"allow":[],"deny":["list_websocket_requests"]}},"deny-send":{"identifier":"deny-send","description":"Denies the send command without any pre-configured scope.","commands":{"allow":[],"deny":["send"]}},"deny-upsert-request":{"identifier":"deny-upsert-request","description":"Denies the upsert_request command without any pre-configured scope.","commands":{"allow":[],"deny":["upsert_request"]}},"deny-upsert-websocket-request":{"identifier":"deny-upsert-websocket-request","description":"Denies the upsert_websocket_request command without any pre-configured scope.","commands":{"allow":[],"deny":["upsert_websocket_request"]}}},"permission_sets":{},"global_scope_schema":null}} \ No newline at end of file diff --git a/src-tauri/gen/schemas/desktop-schema.json b/src-tauri/gen/schemas/desktop-schema.json index 66760a062..1af4d71d3 100644 --- a/src-tauri/gen/schemas/desktop-schema.json +++ b/src-tauri/gen/schemas/desktop-schema.json @@ -37,7 +37,7 @@ ], "definitions": { "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows' and webviews' fine grained access to the Tauri core, application, or plugin commands. If a webview or its window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", "type": "object", "required": [ "identifier", @@ -70,14 +70,14 @@ "type": "boolean" }, "windows": { - "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nOn multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`", + "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nIf a window label matches any of the patterns in this list, the capability will be enabled on all the webviews of that window, regardless of the value of [`Self::webviews`].\n\nOn multiwebview windows, prefer specifying [`Self::webviews`] and omitting [`Self::windows`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`", "type": "array", "items": { "type": "string" } }, "webviews": { - "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThis is only required when using on multiwebview contexts, by default all child webviews of a window that matches [`Self::windows`] are linked.\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`", + "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThe capability will be enabled on all the webviews whose label matches any of the patterns in this list, regardless of whether the webview's window label matches a pattern in [`Self::windows`].\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`", "type": "array", "items": { "type": "string" @@ -2137,11 +2137,26 @@ "type": "string", "const": "core:app:allow-default-window-icon" }, + { + "description": "Enables the fetch_data_store_identifiers command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-fetch-data-store-identifiers" + }, + { + "description": "Enables the identifier command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-identifier" + }, { "description": "Enables the name command without any pre-configured scope.", "type": "string", "const": "core:app:allow-name" }, + { + "description": "Enables the remove_data_store command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-remove-data-store" + }, { "description": "Enables the set_app_theme command without any pre-configured scope.", "type": "string", @@ -2172,11 +2187,26 @@ "type": "string", "const": "core:app:deny-default-window-icon" }, + { + "description": "Denies the fetch_data_store_identifiers command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-fetch-data-store-identifiers" + }, + { + "description": "Denies the identifier command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-identifier" + }, { "description": "Denies the name command without any pre-configured scope.", "type": "string", "const": "core:app:deny-name" }, + { + "description": "Denies the remove_data_store command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-remove-data-store" + }, { "description": "Denies the set_app_theme command without any pre-configured scope.", "type": "string", @@ -2972,6 +3002,11 @@ "type": "string", "const": "core:window:allow-internal-toggle-maximize" }, + { + "description": "Enables the is_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-always-on-top" + }, { "description": "Enables the is_closable command without any pre-configured scope.", "type": "string", @@ -3337,6 +3372,11 @@ "type": "string", "const": "core:window:deny-internal-toggle-maximize" }, + { + "description": "Denies the is_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-always-on-top" + }, { "description": "Denies the is_closable command without any pre-configured scope.", "type": "string", @@ -5592,6 +5632,51 @@ "type": "string", "const": "yaak-license:deny-deactivate" }, + { + "description": "Default permissions for the plugin", + "type": "string", + "const": "yaak-models:default" + }, + { + "description": "Enables the delete command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:allow-delete" + }, + { + "description": "Enables the delete_model command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:allow-delete-model" + }, + { + "description": "Enables the upsert command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:allow-upsert" + }, + { + "description": "Enables the upsert_model command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:allow-upsert-model" + }, + { + "description": "Denies the delete command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:deny-delete" + }, + { + "description": "Denies the delete_model command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:deny-delete-model" + }, + { + "description": "Denies the upsert command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:deny-upsert" + }, + { + "description": "Denies the upsert_model command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:deny-upsert-model" + }, { "description": "Default permissions for the plugin", "type": "string", diff --git a/src-tauri/gen/schemas/macOS-schema.json b/src-tauri/gen/schemas/macOS-schema.json index 66760a062..1af4d71d3 100644 --- a/src-tauri/gen/schemas/macOS-schema.json +++ b/src-tauri/gen/schemas/macOS-schema.json @@ -37,7 +37,7 @@ ], "definitions": { "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows' and webviews' fine grained access to the Tauri core, application, or plugin commands. If a webview or its window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", "type": "object", "required": [ "identifier", @@ -70,14 +70,14 @@ "type": "boolean" }, "windows": { - "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nOn multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`", + "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nIf a window label matches any of the patterns in this list, the capability will be enabled on all the webviews of that window, regardless of the value of [`Self::webviews`].\n\nOn multiwebview windows, prefer specifying [`Self::webviews`] and omitting [`Self::windows`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`", "type": "array", "items": { "type": "string" } }, "webviews": { - "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThis is only required when using on multiwebview contexts, by default all child webviews of a window that matches [`Self::windows`] are linked.\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`", + "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThe capability will be enabled on all the webviews whose label matches any of the patterns in this list, regardless of whether the webview's window label matches a pattern in [`Self::windows`].\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`", "type": "array", "items": { "type": "string" @@ -2137,11 +2137,26 @@ "type": "string", "const": "core:app:allow-default-window-icon" }, + { + "description": "Enables the fetch_data_store_identifiers command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-fetch-data-store-identifiers" + }, + { + "description": "Enables the identifier command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-identifier" + }, { "description": "Enables the name command without any pre-configured scope.", "type": "string", "const": "core:app:allow-name" }, + { + "description": "Enables the remove_data_store command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-remove-data-store" + }, { "description": "Enables the set_app_theme command without any pre-configured scope.", "type": "string", @@ -2172,11 +2187,26 @@ "type": "string", "const": "core:app:deny-default-window-icon" }, + { + "description": "Denies the fetch_data_store_identifiers command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-fetch-data-store-identifiers" + }, + { + "description": "Denies the identifier command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-identifier" + }, { "description": "Denies the name command without any pre-configured scope.", "type": "string", "const": "core:app:deny-name" }, + { + "description": "Denies the remove_data_store command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-remove-data-store" + }, { "description": "Denies the set_app_theme command without any pre-configured scope.", "type": "string", @@ -2972,6 +3002,11 @@ "type": "string", "const": "core:window:allow-internal-toggle-maximize" }, + { + "description": "Enables the is_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-always-on-top" + }, { "description": "Enables the is_closable command without any pre-configured scope.", "type": "string", @@ -3337,6 +3372,11 @@ "type": "string", "const": "core:window:deny-internal-toggle-maximize" }, + { + "description": "Denies the is_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-always-on-top" + }, { "description": "Denies the is_closable command without any pre-configured scope.", "type": "string", @@ -5592,6 +5632,51 @@ "type": "string", "const": "yaak-license:deny-deactivate" }, + { + "description": "Default permissions for the plugin", + "type": "string", + "const": "yaak-models:default" + }, + { + "description": "Enables the delete command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:allow-delete" + }, + { + "description": "Enables the delete_model command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:allow-delete-model" + }, + { + "description": "Enables the upsert command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:allow-upsert" + }, + { + "description": "Enables the upsert_model command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:allow-upsert-model" + }, + { + "description": "Denies the delete command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:deny-delete" + }, + { + "description": "Denies the delete_model command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:deny-delete-model" + }, + { + "description": "Denies the upsert command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:deny-upsert" + }, + { + "description": "Denies the upsert_model command without any pre-configured scope.", + "type": "string", + "const": "yaak-models:deny-upsert-model" + }, { "description": "Default permissions for the plugin", "type": "string", diff --git a/src-tauri/src/error.rs b/src-tauri/src/error.rs index 4c775897f..6bd5ddaa5 100644 --- a/src-tauri/src/error.rs +++ b/src-tauri/src/error.rs @@ -3,27 +3,30 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum Error { - #[error("Render error: {0}")] + #[error(transparent)] TemplateError(#[from] yaak_templates::error::Error), - #[error("Model error: {0}")] + #[error(transparent)] ModelError(#[from] yaak_models::error::Error), - #[error("Sync error: {0}")] + #[error(transparent)] SyncError(#[from] yaak_sync::error::Error), - #[error("Git error: {0}")] + #[error(transparent)] GitError(#[from] yaak_git::error::Error), - #[error("Websocket error: {0}")] + #[error(transparent)] WebsocketError(#[from] yaak_ws::error::Error), - #[error("License error: {0}")] + #[error(transparent)] LicenseError(#[from] yaak_license::error::Error), - #[error("Plugin error: {0}")] + #[error(transparent)] PluginError(#[from] yaak_plugins::error::Error), + #[error("Updater error: {0}")] + UpdaterError(#[from] tauri_plugin_updater::Error), + #[error("Request error: {0}")] RequestError(#[from] reqwest::Error), diff --git a/src-tauri/src/history.rs b/src-tauri/src/history.rs index 7bc5ff35d..1e92f1e19 100644 --- a/src-tauri/src/history.rs +++ b/src-tauri/src/history.rs @@ -1,8 +1,6 @@ use tauri::{AppHandle, Runtime}; - -use yaak_models::queries::{ - get_key_value_int, get_key_value_string, set_key_value_int, set_key_value_string, UpdateSource, -}; +use yaak_models::manager::QueryManagerExt; +use yaak_models::queries_legacy::UpdateSource; const NAMESPACE: &str = "analytics"; const NUM_LAUNCHES_KEY: &str = "num_launches"; @@ -21,34 +19,28 @@ pub async fn store_launch_history(app_handle: &AppHandle) -> Laun let mut info = LaunchEventInfo::default(); info.num_launches = get_num_launches(app_handle).await + 1; - info.previous_version = - get_key_value_string(app_handle, NAMESPACE, last_tracked_version_key, "").await; info.current_version = app_handle.package_info().version.to_string(); - if info.previous_version.is_empty() { - } else { - info.launched_after_update = info.current_version != info.previous_version; - }; + app_handle + .queries() + .with_tx(|tx| { + info.previous_version = + tx.get_key_value_string(NAMESPACE, last_tracked_version_key, ""); - // Update key values + if !info.previous_version.is_empty() { + info.launched_after_update = info.current_version != info.previous_version; + }; - set_key_value_string( - app_handle, - NAMESPACE, - last_tracked_version_key, - info.current_version.as_str(), - &UpdateSource::Background, - ) - .await; + // Update key values - set_key_value_int( - app_handle, - NAMESPACE, - NUM_LAUNCHES_KEY, - info.num_launches, - &UpdateSource::Background, - ) - .await; + let source = &UpdateSource::Background; + let version = info.current_version.as_str(); + tx.set_key_value_string(NAMESPACE, last_tracked_version_key, version, source); + tx.set_key_value_int(NAMESPACE, NUM_LAUNCHES_KEY, info.num_launches, source); + Ok(()) + }) + .await + .unwrap(); info } @@ -66,5 +58,5 @@ pub fn get_os() -> &'static str { } pub async fn get_num_launches(app_handle: &AppHandle) -> i32 { - get_key_value_int(app_handle, NAMESPACE, NUM_LAUNCHES_KEY, 0).await + app_handle.queries().connect().await.unwrap().get_key_value_int(NAMESPACE, NUM_LAUNCHES_KEY, 0) } diff --git a/src-tauri/src/http_request.rs b/src-tauri/src/http_request.rs index ec2f0902b..ad3396895 100644 --- a/src-tauri/src/http_request.rs +++ b/src-tauri/src/http_request.rs @@ -24,14 +24,12 @@ use tokio::fs::{create_dir_all, File}; use tokio::io::AsyncWriteExt; use tokio::sync::watch::Receiver; use tokio::sync::{oneshot, Mutex}; +use yaak_models::manager::QueryManagerExt; use yaak_models::models::{ Cookie, CookieJar, Environment, HttpRequest, HttpResponse, HttpResponseHeader, HttpResponseState, ProxySetting, ProxySettingAuth, }; -use yaak_models::queries::{ - get_base_environment, get_http_response, get_or_create_settings, get_workspace, - update_response_if_id, upsert_cookie_jar, UpdateSource, -}; +use yaak_models::queries_legacy::UpdateSource; use yaak_plugins::events::{ CallHttpAuthenticationRequest, HttpHeader, RenderPurpose, WindowContext, }; @@ -48,10 +46,18 @@ pub async fn send_http_request( ) -> Result { let app_handle = window.app_handle().clone(); let plugin_manager = app_handle.state::(); - let workspace = get_workspace(&app_handle, &unrendered_request.workspace_id).await?; - let base_environment = - get_base_environment(&app_handle, &unrendered_request.workspace_id).await?; - let settings = get_or_create_settings(&app_handle).await; + let update_source = &UpdateSource::from_window(&window); + let (settings, workspace) = { + let db = window.queries().connect().await?; + let settings = db.get_or_create_settings(update_source)?; + let workspace = db.get_workspace(&unrendered_request.workspace_id)?; + (settings, workspace) + }; + let base_environment = app_handle + .queries() + .connect() + .await? + .get_base_environment(&unrendered_request.workspace_id)?; let response_id = og_response.id.clone(); let response = Arc::new(Mutex::new(og_response.clone())); @@ -534,8 +540,12 @@ pub async fn send_http_request( }; r.state = HttpResponseState::Connected; - update_response_if_id(&app_handle, &r, &update_source) + app_handle + .queries() + .connect() .await + .unwrap() + .update_http_response_if_id(&r, &update_source) .expect("Failed to update response after connected"); } @@ -563,8 +573,12 @@ pub async fn send_http_request( f.flush().await.expect("Failed to flush file"); written_bytes += bytes.len(); r.content_length = Some(written_bytes as i32); - update_response_if_id(&app_handle, &r, &update_source) + app_handle + .queries() + .connect() .await + .unwrap() + .update_http_response_if_id(&r, &update_source) .expect("Failed to update response"); } Ok(None) => { @@ -591,8 +605,12 @@ pub async fn send_http_request( None => Some(written_bytes as i32), }; r.state = HttpResponseState::Closed; - update_response_if_id(&app_handle, &r, &UpdateSource::from_window(&window)) + app_handle + .queries() + .connect() .await + .unwrap() + .update_http_response_if_id(&r, &UpdateSource::from_window(&window)) .expect("Failed to update response"); }; @@ -617,12 +635,12 @@ pub async fn send_http_request( }) .collect::>(); cookie_jar.cookies = json_cookies; - if let Err(e) = upsert_cookie_jar( - &app_handle, - &cookie_jar, - &UpdateSource::from_window(&window), - ) - .await + if let Err(e) = app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_cookie_jar(&cookie_jar, &UpdateSource::from_window(&window)) { error!("Failed to update cookie jar: {}", e); }; @@ -649,10 +667,16 @@ pub async fn send_http_request( Ok(tokio::select! { Ok(r) = done_rx => r, _ = cancelled_rx.changed() => { - match get_http_response(&app_handle, response_id.as_str()).await { + match app_handle.queries().with_conn(|c| c.get_http_response(&response_id)).await { Ok(mut r) => { r.state = HttpResponseState::Closed; - update_response_if_id(&app_handle, &r, &UpdateSource::from_window(window)).await.expect("Failed to update response") + app_handle + .queries() + .connect() + .await + .unwrap() + .update_http_response_if_id(&r, &UpdateSource::from_window(window)) + .expect("Failed to update response") }, _ => { response_err(&app_handle, &*response.lock().await, "Ephemeral request was cancelled".to_string(), &update_source).await diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index e647c784f..bc4832524 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -30,30 +30,14 @@ use tokio::sync::Mutex; use tokio::task::block_in_place; use yaak_grpc::manager::{DynamicMessage, GrpcHandle}; use yaak_grpc::{deserialize_message, serialize_message, Code, ServiceDefinition}; +use yaak_models::manager::QueryManagerExt; use yaak_models::models::{ CookieJar, Environment, EnvironmentVariable, Folder, GrpcConnection, GrpcConnectionState, GrpcEvent, GrpcEventType, GrpcRequest, HttpRequest, HttpResponse, HttpResponseState, KeyValue, ModelType, Plugin, Settings, WebsocketRequest, Workspace, WorkspaceMeta, }; -use yaak_models::queries::{ - batch_upsert, cancel_pending_grpc_connections, cancel_pending_http_responses, - cancel_pending_websocket_connections, create_default_http_response, - delete_all_grpc_connections, delete_all_grpc_connections_for_workspace, - delete_all_http_responses_for_request, delete_all_http_responses_for_workspace, - delete_all_websocket_connections_for_workspace, delete_cookie_jar, delete_environment, - delete_folder, delete_grpc_connection, delete_grpc_request, delete_http_request, - delete_http_response, delete_plugin, delete_workspace, duplicate_folder, - duplicate_grpc_request, duplicate_http_request, ensure_base_environment, generate_model_id, - get_base_environment, get_cookie_jar, get_environment, get_folder, get_grpc_connection, - get_grpc_request, get_http_request, get_http_response, get_key_value_raw, - get_or_create_settings, get_or_create_workspace_meta, get_plugin, get_workspace, - get_workspace_export_resources, list_cookie_jars, list_environments, list_folders, - list_grpc_connections_for_workspace, list_grpc_events, list_grpc_requests, list_http_requests, - list_http_responses_for_workspace, list_key_values_raw, list_plugins, list_workspaces, - set_key_value_raw, update_response_if_id, update_settings, upsert_cookie_jar, - upsert_environment, upsert_folder, upsert_grpc_connection, upsert_grpc_event, - upsert_grpc_request, upsert_http_request, upsert_plugin, upsert_workspace, - upsert_workspace_meta, BatchUpsertResult, UpdateSource, +use yaak_models::queries_legacy::{ + generate_model_id, get_workspace_export_resources, BatchUpsertResult, UpdateSource, }; use yaak_plugins::events::{ BootResponse, CallHttpAuthenticationRequest, CallHttpRequestActionRequest, FilterResponse, @@ -124,10 +108,11 @@ async fn cmd_render_template( environment_id: Option<&str>, ) -> YaakResult { let environment = match environment_id { - Some(id) => get_environment(&app_handle, id).await.ok(), + Some(id) => app_handle.queries().connect().await?.get_environment(id).ok(), None => None, }; - let base_environment = get_base_environment(&app_handle, &workspace_id).await?; + let base_environment = + app_handle.queries().connect().await?.get_base_environment(&workspace_id)?; let result = render_template( template, &base_environment, @@ -157,15 +142,17 @@ async fn cmd_grpc_reflect( proto_files: Vec, app_handle: AppHandle, grpc_handle: State<'_, Mutex>, -) -> Result, String> { - let req = get_grpc_request(&app_handle, request_id) - .await - .map_err(|e| e.to_string())? - .ok_or("Failed to find GRPC request")?; +) -> YaakResult> { + let req = app_handle + .queries() + .connect() + .await? + .get_grpc_request(request_id)? + .ok_or(GenericError("Failed to find GRPC request".to_string()))?; let uri = safe_uri(&req.url); - grpc_handle + Ok(grpc_handle .lock() .await .services( @@ -174,6 +161,7 @@ async fn cmd_grpc_reflect( &proto_files.iter().map(|p| PathBuf::from_str(p).unwrap()).collect(), ) .await + .map_err(|e| GenericError(e.to_string()))?) } #[tauri::command] @@ -187,14 +175,20 @@ async fn cmd_grpc_go( grpc_handle: State<'_, Mutex>, ) -> YaakResult { let environment = match environment_id { - Some(id) => get_environment(&app_handle, id).await.ok(), + Some(id) => app_handle.queries().connect().await?.get_environment(id).ok(), None => None, }; - let unrendered_request = get_grpc_request(&app_handle, request_id) + let unrendered_request = app_handle + .queries() + .connect() .await? + .get_grpc_request(request_id)? .ok_or(GenericError("Failed to get GRPC request".to_string()))?; - let base_environment = - get_base_environment(&app_handle, &unrendered_request.workspace_id).await?; + let base_environment = app_handle + .queries() + .connect() + .await? + .get_base_environment(&unrendered_request.workspace_id)?; let request = render_grpc_request( &unrendered_request, &base_environment, @@ -243,8 +237,7 @@ async fn cmd_grpc_go( } } - let conn = upsert_grpc_connection( - &app_handle, + let conn = app_handle.queries().connect().await?.upsert_grpc_connection( &GrpcConnection { workspace_id: request.workspace_id.clone(), request_id: request.id.clone(), @@ -255,8 +248,7 @@ async fn cmd_grpc_go( ..Default::default() }, &UpdateSource::from_window(&window), - ) - .await?; + )?; let conn_id = conn.id.clone(); @@ -297,8 +289,7 @@ async fn cmd_grpc_go( let connection = match connection { Ok(c) => c, Err(err) => { - upsert_grpc_connection( - &app_handle, + app_handle.queries().connect().await?.upsert_grpc_connection( &GrpcConnection { elapsed: start.elapsed().as_millis() as i32, error: Some(err.clone()), @@ -306,8 +297,7 @@ async fn cmd_grpc_go( ..conn.clone() }, &UpdateSource::from_window(&window), - ) - .await?; + )?; return Ok(conn_id); } }; @@ -373,34 +363,40 @@ async fn cmd_grpc_go( Ok(d_msg) => d_msg, Err(e) => { tauri::async_runtime::spawn(async move { - upsert_grpc_event( - &app_handle, - &GrpcEvent { - event_type: GrpcEventType::Error, - content: e.to_string(), - ..base_msg.clone() - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &GrpcEvent { + event_type: GrpcEventType::Error, + content: e.to_string(), + ..base_msg.clone() + }, + &UpdateSource::from_window(&window), + ) + .unwrap(); }); return; } }; in_msg_tx.try_send(d_msg).unwrap(); tauri::async_runtime::spawn(async move { - upsert_grpc_event( - &app_handle, - &GrpcEvent { - content: msg, - event_type: GrpcEventType::ClientMessage, - ..base_msg.clone() - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &GrpcEvent { + content: msg, + event_type: GrpcEventType::ClientMessage, + ..base_msg.clone() + }, + &UpdateSource::from_window(&window), + ) + .unwrap(); }); } Ok(IncomingMsg::Commit) => { @@ -435,8 +431,7 @@ async fn cmd_grpc_go( ) .await?; - upsert_grpc_event( - &app_handle, + app_handle.queries().connect().await?.upsert_grpc_event( &GrpcEvent { content: format!("Connecting to {}", req.url), event_type: GrpcEventType::ConnectionStart, @@ -444,8 +439,7 @@ async fn cmd_grpc_go( ..base_event.clone() }, &UpdateSource::from_window(&window), - ) - .await?; + )?; async move { let (maybe_stream, maybe_msg) = @@ -474,86 +468,101 @@ async fn cmd_grpc_go( }; if !method_desc.is_client_streaming() { - upsert_grpc_event( - &app_handle, - &GrpcEvent { - event_type: GrpcEventType::ClientMessage, - content: msg, - ..base_event.clone() - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); - } - - match maybe_msg { - Some(Ok(msg)) => { - upsert_grpc_event( - &app_handle, - &GrpcEvent { - metadata: metadata_to_map(msg.metadata().clone()), - content: if msg.metadata().len() == 0 { - "Received response" - } else { - "Received response with metadata" - } - .to_string(), - event_type: GrpcEventType::Info, - ..base_event.clone() - }, - &UpdateSource::from_window(&window), - ) + app_handle + .queries() + .connect() .await - .unwrap(); - upsert_grpc_event( - &app_handle, + .unwrap() + .upsert_grpc_event( &GrpcEvent { - content: serialize_message(&msg.into_inner()).unwrap(), - event_type: GrpcEventType::ServerMessage, + event_type: GrpcEventType::ClientMessage, + content: msg, ..base_event.clone() }, &UpdateSource::from_window(&window), ) - .await .unwrap(); - upsert_grpc_event( - &app_handle, - &GrpcEvent { - content: "Connection complete".to_string(), - event_type: GrpcEventType::ConnectionEnd, - status: Some(Code::Ok as i32), - ..base_event.clone() - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); - } - Some(Err(e)) => { - upsert_grpc_event( - &app_handle, - &(match e.status { - Some(s) => GrpcEvent { - error: Some(s.message().to_string()), - status: Some(s.code() as i32), - content: "Failed to connect".to_string(), - metadata: metadata_to_map(s.metadata().clone()), - event_type: GrpcEventType::ConnectionEnd, + } + + match maybe_msg { + Some(Ok(msg)) => { + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &GrpcEvent { + metadata: metadata_to_map(msg.metadata().clone()), + content: if msg.metadata().len() == 0 { + "Received response" + } else { + "Received response with metadata" + } + .to_string(), + event_type: GrpcEventType::Info, ..base_event.clone() }, - None => GrpcEvent { - error: Some(e.message), - status: Some(Code::Unknown as i32), - content: "Failed to connect".to_string(), + &UpdateSource::from_window(&window), + ) + .unwrap(); + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &GrpcEvent { + content: serialize_message(&msg.into_inner()).unwrap(), + event_type: GrpcEventType::ServerMessage, + ..base_event.clone() + }, + &UpdateSource::from_window(&window), + ) + .unwrap(); + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &GrpcEvent { + content: "Connection complete".to_string(), event_type: GrpcEventType::ConnectionEnd, + status: Some(Code::Ok as i32), ..base_event.clone() }, - }), - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + &UpdateSource::from_window(&window), + ) + .unwrap(); + } + Some(Err(e)) => { + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &(match e.status { + Some(s) => GrpcEvent { + error: Some(s.message().to_string()), + status: Some(s.code() as i32), + content: "Failed to connect".to_string(), + metadata: metadata_to_map(s.metadata().clone()), + event_type: GrpcEventType::ConnectionEnd, + ..base_event.clone() + }, + None => GrpcEvent { + error: Some(e.message), + status: Some(Code::Unknown as i32), + content: "Failed to connect".to_string(), + event_type: GrpcEventType::ConnectionEnd, + ..base_event.clone() + }, + }), + &UpdateSource::from_window(&window), + ) + .unwrap(); } None => { // Server streaming doesn't return the initial message @@ -562,50 +571,56 @@ async fn cmd_grpc_go( let mut stream = match maybe_stream { Some(Ok(stream)) => { - upsert_grpc_event( - &app_handle, - &GrpcEvent { - metadata: metadata_to_map(stream.metadata().clone()), - content: if stream.metadata().len() == 0 { - "Received response" - } else { - "Received response with metadata" - } - .to_string(), - event_type: GrpcEventType::Info, - ..base_event.clone() - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &GrpcEvent { + metadata: metadata_to_map(stream.metadata().clone()), + content: if stream.metadata().len() == 0 { + "Received response" + } else { + "Received response with metadata" + } + .to_string(), + event_type: GrpcEventType::Info, + ..base_event.clone() + }, + &UpdateSource::from_window(&window), + ) + .unwrap(); stream.into_inner() } Some(Err(e)) => { warn!("GRPC stream error {e:?}"); - upsert_grpc_event( - &app_handle, - &(match e.status { - Some(s) => GrpcEvent { - error: Some(s.message().to_string()), - status: Some(s.code() as i32), - content: "Failed to connect".to_string(), - metadata: metadata_to_map(s.metadata().clone()), - event_type: GrpcEventType::ConnectionEnd, - ..base_event.clone() - }, - None => GrpcEvent { - error: Some(e.message), - status: Some(Code::Unknown as i32), - content: "Failed to connect".to_string(), - event_type: GrpcEventType::ConnectionEnd, - ..base_event.clone() - }, - }), - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &(match e.status { + Some(s) => GrpcEvent { + error: Some(s.message().to_string()), + status: Some(s.code() as i32), + content: "Failed to connect".to_string(), + metadata: metadata_to_map(s.metadata().clone()), + event_type: GrpcEventType::ConnectionEnd, + ..base_event.clone() + }, + None => GrpcEvent { + error: Some(e.message), + status: Some(Code::Unknown as i32), + content: "Failed to connect".to_string(), + event_type: GrpcEventType::ConnectionEnd, + ..base_event.clone() + }, + }), + &UpdateSource::from_window(&window), + ) + .unwrap(); return; } None => return, @@ -615,50 +630,59 @@ async fn cmd_grpc_go( match stream.message().await { Ok(Some(msg)) => { let message = serialize_message(&msg).unwrap(); - upsert_grpc_event( - &app_handle, - &GrpcEvent { - content: message, - event_type: GrpcEventType::ServerMessage, - ..base_event.clone() - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &GrpcEvent { + content: message, + event_type: GrpcEventType::ServerMessage, + ..base_event.clone() + }, + &UpdateSource::from_window(&window), + ) + .unwrap(); } Ok(None) => { let trailers = stream.trailers().await.unwrap_or_default().unwrap_or_default(); - upsert_grpc_event( - &app_handle, - &GrpcEvent { - content: "Connection complete".to_string(), - status: Some(Code::Ok as i32), - metadata: metadata_to_map(trailers), - event_type: GrpcEventType::ConnectionEnd, - ..base_event.clone() - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &GrpcEvent { + content: "Connection complete".to_string(), + status: Some(Code::Ok as i32), + metadata: metadata_to_map(trailers), + event_type: GrpcEventType::ConnectionEnd, + ..base_event.clone() + }, + &UpdateSource::from_window(&window), + ) + .unwrap(); break; } Err(status) => { - upsert_grpc_event( - &app_handle, - &GrpcEvent { - content: status.to_string(), - status: Some(status.code() as i32), - metadata: metadata_to_map(status.metadata().clone()), - event_type: GrpcEventType::ConnectionEnd, - ..base_event.clone() - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_grpc_event( + &GrpcEvent { + content: status.to_string(), + status: Some(status.code() as i32), + metadata: metadata_to_map(status.metadata().clone()), + event_type: GrpcEventType::ConnectionEnd, + ..base_event.clone() + }, + &UpdateSource::from_window(&window), + ) + .unwrap(); } } } @@ -671,27 +695,25 @@ async fn cmd_grpc_go( let w = app_handle.clone(); tokio::select! { _ = grpc_listen => { - let events = list_grpc_events(&w, &conn_id) - .await - .unwrap(); + let events = w.queries().connect().await.unwrap().list_grpc_events(&conn_id).unwrap(); let closed_event = events .iter() .find(|e| GrpcEventType::ConnectionEnd == e.event_type); let closed_status = closed_event.and_then(|e| e.status).unwrap_or(Code::Unavailable as i32); - upsert_grpc_connection( - &w, - &GrpcConnection{ - elapsed: start.elapsed().as_millis() as i32, - status: closed_status, - state: GrpcConnectionState::Closed, - ..get_grpc_connection(&w, &conn_id).await.unwrap().clone() - }, - &UpdateSource::from_window(&window), - ).await.unwrap(); + w.queries().with_conn(|c| { + c.upsert_grpc_connection( + &GrpcConnection{ + elapsed: start.elapsed().as_millis() as i32, + status: closed_status, + state: GrpcConnectionState::Closed, + ..c.get_grpc_connection( &conn_id).unwrap().clone() + }, + &UpdateSource::from_window(&window), + ) + }).await.unwrap(); }, _ = cancelled_rx.changed() => { - upsert_grpc_event( - &w, + w.queries().connect().await.unwrap().upsert_grpc_event( &GrpcEvent { content: "Cancelled".to_string(), event_type: GrpcEventType::ConnectionEnd, @@ -699,19 +721,18 @@ async fn cmd_grpc_go( ..base_msg.clone() }, &UpdateSource::from_window(&window), - ).await.unwrap(); - upsert_grpc_connection( - &w, - &GrpcConnection { + ).unwrap(); + w.queries().with_conn(|c| { + c.upsert_grpc_connection( + &GrpcConnection{ elapsed: start.elapsed().as_millis() as i32, status: Code::Cancelled as i32, state: GrpcConnectionState::Closed, - ..get_grpc_connection(&w, &conn_id).await.unwrap().clone() - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + ..c.get_grpc_connection( &conn_id).unwrap().clone() + }, + &UpdateSource::from_window(&window), + ) + }).await.unwrap(); }, } w.unlisten(event_handler); @@ -729,16 +750,14 @@ async fn cmd_send_ephemeral_request( window: WebviewWindow, app_handle: AppHandle, ) -> YaakResult { - let response = HttpResponse::new(); + let response = HttpResponse::default(); request.id = "".to_string(); let environment = match environment_id { - Some(id) => { - Some(get_environment(&app_handle, id).await.expect("Failed to get environment")) - } + Some(id) => Some(app_handle.queries().connect().await?.get_environment(id)?), None => None, }; let cookie_jar = match cookie_jar_id { - Some(id) => Some(get_cookie_jar(&app_handle, id).await.expect("Failed to get cookie jar")), + Some(id) => Some(app_handle.queries().connect().await?.get_cookie_jar(id)?), None => None, }; @@ -764,12 +783,11 @@ async fn cmd_filter_response( response_id: &str, plugin_manager: State<'_, PluginManager>, filter: &str, -) -> Result { - let response = - get_http_response(&app_handle, response_id).await.expect("Failed to get http response"); +) -> YaakResult { + let response = app_handle.queries().connect().await?.get_http_response(response_id)?; if let None = response.body_path { - return Err("Response body path not set".to_string()); + return Err(GenericError("Response body path not set".to_string())); } let mut content_type = "".to_string(); @@ -780,13 +798,12 @@ async fn cmd_filter_response( } } - let body = read_response_body(response).await.unwrap(); + let body = read_response_body(response) + .await + .ok_or(GenericError("Failed to find response body".to_string()))?; // TODO: Have plugins register their own content type (regex?) - plugin_manager - .filter_data(&window, filter, &body, &content_type) - .await - .map_err(|e| e.to_string()) + Ok(plugin_manager.filter_data(&window, filter, &body, &content_type).await?) } #[tauri::command] @@ -816,13 +833,12 @@ async fn cmd_import_data( app_handle: AppHandle, plugin_manager: State<'_, PluginManager>, file_path: &str, -) -> Result { +) -> YaakResult { let file = read_to_string(file_path) .await .unwrap_or_else(|_| panic!("Unable to read file {}", file_path)); let file_contents = file.as_str(); - let import_result = - plugin_manager.import_data(&window, file_contents).await.map_err(|e| e.to_string())?; + let import_result = plugin_manager.import_data(&window, file_contents).await?; let mut id_map: BTreeMap = BTreeMap::new(); @@ -924,18 +940,20 @@ async fn cmd_import_data( }) .collect(); - let upserted = batch_upsert( - &app_handle, - workspaces, - environments, - folders, - http_requests, - grpc_requests, - websocket_requests, - &UpdateSource::Import, - ) - .await - .map_err(|e| e.to_string())?; + let upserted = app_handle + .queries() + .with_tx(|tx| { + tx.batch_upsert( + workspaces, + environments, + folders, + http_requests, + grpc_requests, + websocket_requests, + &UpdateSource::Import, + ) + }) + .await?; Ok(upserted) } @@ -1058,17 +1076,12 @@ async fn cmd_save_response( app_handle: AppHandle, response_id: &str, filepath: &str, -) -> Result<(), String> { - let response = get_http_response(&app_handle, response_id).await.map_err(|e| e.to_string())?; - - let body_path = match response.body_path { - None => { - return Err("Response does not have a body".to_string()); - } - Some(p) => p, - }; +) -> YaakResult<()> { + let response = app_handle.queries().connect().await?.get_http_response(response_id)?; - fs::copy(body_path, filepath).map_err(|e| e.to_string())?; + let body_path = + response.body_path.ok_or(GenericError("Response does not have a body".to_string()))?; + fs::copy(body_path, filepath).map_err(|e| GenericError(e.to_string()))?; Ok(()) } @@ -1084,9 +1097,14 @@ async fn cmd_send_http_request( // that has not yet been saved in the DB. request: HttpRequest, ) -> YaakResult { - let response = - create_default_http_response(&app_handle, &request.id, &UpdateSource::from_window(&window)) - .await?; + let response = app_handle.queries().connect().await?.upsert_http_response( + &HttpResponse { + request_id: request.id.clone(), + workspace_id: request.workspace_id.clone(), + ..Default::default() + }, + &UpdateSource::from_window(&window), + )?; let (cancel_tx, mut cancel_rx) = tokio::sync::watch::channel(false); app_handle.listen_any(format!("cancel_http_response_{}", response.id), move |_event| { @@ -1096,7 +1114,7 @@ async fn cmd_send_http_request( }); let environment = match environment_id { - Some(id) => match get_environment(&app_handle, id).await { + Some(id) => match app_handle.queries().connect().await?.get_environment(id) { Ok(env) => Some(env), Err(e) => { warn!("Failed to find environment by id {id} {}", e); @@ -1107,7 +1125,7 @@ async fn cmd_send_http_request( }; let cookie_jar = match cookie_jar_id { - Some(id) => Some(get_cookie_jar(&app_handle, id).await.expect("Failed to get cookie jar")), + Some(id) => Some(app_handle.queries().connect().await?.get_cookie_jar(id)?), None => None, }; @@ -1124,8 +1142,12 @@ async fn response_err( let mut response = response.clone(); response.state = HttpResponseState::Closed; response.error = Some(error.clone()); - response = update_response_if_id(app_handle, &response, update_source) + response = app_handle + .queries() + .connect() .await + .unwrap() + .update_http_response_if_id(&response, update_source) .expect("Failed to update response"); response } @@ -1136,14 +1158,12 @@ async fn cmd_set_update_mode( app_handle: AppHandle, window: WebviewWindow, ) -> YaakResult { - let (key_value, _created) = set_key_value_raw( - &app_handle, + let (key_value, _created) = app_handle.queries().connect().await?.set_key_value_raw( "app", "update_mode", update_mode, &UpdateSource::from_window(&window), - ) - .await; + ); Ok(key_value) } @@ -1152,9 +1172,8 @@ async fn cmd_get_key_value( namespace: &str, key: &str, app_handle: AppHandle, -) -> Result, ()> { - let result = get_key_value_raw(&app_handle, namespace, key).await; - Ok(result) +) -> YaakResult> { + Ok(app_handle.queries().connect().await?.get_key_value_raw(namespace, key)) } #[tauri::command] @@ -1164,10 +1183,13 @@ async fn cmd_set_key_value( namespace: &str, key: &str, value: &str, -) -> Result { - let (key_value, _created) = - set_key_value_raw(&app_handle, namespace, key, value, &UpdateSource::from_window(&window)) - .await; +) -> YaakResult { + let (key_value, _created) = app_handle.queries().connect().await?.set_key_value_raw( + namespace, + key, + value, + &UpdateSource::from_window(&window), + ); Ok(key_value) } @@ -1178,25 +1200,19 @@ async fn cmd_install_plugin( plugin_manager: State<'_, PluginManager>, app_handle: AppHandle, window: WebviewWindow, -) -> Result { +) -> YaakResult { plugin_manager .add_plugin_by_dir(&WindowContext::from_window(&window), &directory, true) - .await - .map_err(|e| e.to_string())?; + .await?; - let plugin = upsert_plugin( - &app_handle, - Plugin { + Ok(app_handle.queries().connect().await?.upsert_plugin( + &Plugin { directory: directory.into(), url, ..Default::default() }, &UpdateSource::from_window(&window), - ) - .await - .map_err(|e| e.to_string())?; - - Ok(plugin) + )?) } #[tauri::command] @@ -1205,15 +1221,16 @@ async fn cmd_uninstall_plugin( plugin_manager: State<'_, PluginManager>, window: WebviewWindow, app_handle: AppHandle, -) -> Result { - let plugin = delete_plugin(&app_handle, plugin_id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string())?; +) -> YaakResult { + let plugin = app_handle + .queries() + .connect() + .await? + .delete_plugin_by_id(plugin_id, &UpdateSource::from_window(&window))?; plugin_manager .uninstall(&WindowContext::from_window(&window), plugin.directory.as_str()) - .await - .map_err(|e| e.to_string())?; + .await?; Ok(plugin) } @@ -1223,10 +1240,12 @@ async fn cmd_update_cookie_jar( cookie_jar: CookieJar, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - upsert_cookie_jar(&app_handle, &cookie_jar, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .upsert_cookie_jar(&cookie_jar, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1234,10 +1253,12 @@ async fn cmd_delete_cookie_jar( app_handle: AppHandle, window: WebviewWindow, cookie_jar_id: &str, -) -> Result { - delete_cookie_jar(&app_handle, cookie_jar_id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .delete_cookie_jar_by_id(cookie_jar_id, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1246,18 +1267,15 @@ async fn cmd_create_cookie_jar( name: &str, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - upsert_cookie_jar( - &app_handle, +) -> YaakResult { + Ok(app_handle.queries().connect().await?.upsert_cookie_jar( &CookieJar { name: name.to_string(), workspace_id: workspace_id.to_string(), ..Default::default() }, &UpdateSource::from_window(&window), - ) - .await - .map_err(|e| e.to_string()) + )?) } #[tauri::command] @@ -1268,10 +1286,9 @@ async fn cmd_create_environment( variables: Vec, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - upsert_environment( - &app_handle, - Environment { +) -> YaakResult { + Ok(app_handle.queries().connect().await?.upsert_environment( + &Environment { workspace_id: workspace_id.to_string(), environment_id: environment_id.map(|s| s.to_string()), name: name.to_string(), @@ -1279,9 +1296,7 @@ async fn cmd_create_environment( ..Default::default() }, &UpdateSource::from_window(&window), - ) - .await - .map_err(|e| e.to_string()) + )?) } #[tauri::command] @@ -1292,10 +1307,9 @@ async fn cmd_create_grpc_request( folder_id: Option<&str>, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - upsert_grpc_request( - &app_handle, - GrpcRequest { +) -> YaakResult { + Ok(app_handle.queries().connect().await?.upsert_grpc_request( + &GrpcRequest { workspace_id: workspace_id.to_string(), name: name.to_string(), folder_id: folder_id.map(|s| s.to_string()), @@ -1303,9 +1317,7 @@ async fn cmd_create_grpc_request( ..Default::default() }, &UpdateSource::from_window(&window), - ) - .await - .map_err(|e| e.to_string()) + )?) } #[tauri::command] @@ -1313,10 +1325,10 @@ async fn cmd_duplicate_grpc_request( id: &str, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - duplicate_grpc_request(&app_handle, id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + let db = app_handle.queries().connect().await?; + let request = db.get_grpc_request(id)?.unwrap(); + Ok(db.duplicate_grpc_request(&request, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1324,22 +1336,10 @@ async fn cmd_duplicate_folder( app_handle: AppHandle, window: WebviewWindow, id: &str, -) -> YaakResult<()> { - let folder = get_folder(&app_handle, id).await?; - let new_folder = - duplicate_folder(&app_handle, &folder, &UpdateSource::from_window(&window)).await?; - Ok(new_folder) -} - -#[tauri::command] -async fn cmd_create_http_request( - request: HttpRequest, - app_handle: AppHandle, - window: WebviewWindow, -) -> Result { - upsert_http_request(&app_handle, request, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + let db = app_handle.queries().connect().await?; + let folder = db.get_folder(id)?; + Ok(db.duplicate_folder(&folder, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1347,10 +1347,10 @@ async fn cmd_duplicate_http_request( id: &str, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - duplicate_http_request(&app_handle, id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + let db = app_handle.queries().connect().await?; + let request = db.get_http_request(id)?.unwrap(); + Ok(db.duplicate_http_request(&request, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1358,10 +1358,12 @@ async fn cmd_update_workspace( workspace: Workspace, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - upsert_workspace(&app_handle, workspace, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .upsert_workspace(&workspace, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1369,10 +1371,12 @@ async fn cmd_update_workspace_meta( workspace_meta: WorkspaceMeta, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - upsert_workspace_meta(&app_handle, workspace_meta, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .upsert_workspace_meta(&workspace_meta, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1380,10 +1384,12 @@ async fn cmd_update_environment( environment: Environment, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - upsert_environment(&app_handle, environment, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .upsert_environment(&environment, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1391,21 +1397,25 @@ async fn cmd_update_grpc_request( request: GrpcRequest, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - upsert_grpc_request(&app_handle, request, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .upsert_grpc_request(&request, &UpdateSource::from_window(&window))?) } #[tauri::command] -async fn cmd_update_http_request( +async fn cmd_upsert_http_request( request: HttpRequest, - app_handle: AppHandle, window: WebviewWindow, -) -> Result { - upsert_http_request(&app_handle, request, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) + app_handle: AppHandle, +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .upsert(&request, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1413,10 +1423,12 @@ async fn cmd_delete_grpc_request( app_handle: AppHandle, request_id: &str, window: WebviewWindow, -) -> Result { - delete_grpc_request(&app_handle, request_id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .delete_grpc_request_by_id(request_id, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1424,18 +1436,20 @@ async fn cmd_delete_http_request( app_handle: AppHandle, request_id: &str, window: WebviewWindow, -) -> Result { - delete_http_request(&app_handle, request_id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .delete_http_request_by_id(request_id, &UpdateSource::from_window(&window))?) } #[tauri::command] async fn cmd_list_folders( workspace_id: &str, app_handle: AppHandle, -) -> Result, String> { - list_folders(&app_handle, workspace_id).await.map_err(|e| e.to_string()) +) -> YaakResult> { + Ok(app_handle.queries().connect().await?.list_folders(workspace_id)?) } #[tauri::command] @@ -1444,7 +1458,11 @@ async fn cmd_update_folder( app_handle: AppHandle, window: WebviewWindow, ) -> YaakResult { - Ok(upsert_folder(&app_handle, folder, &UpdateSource::from_window(&window)).await?) + Ok(app_handle + .queries() + .connect() + .await? + .upsert_folder(&folder, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1452,10 +1470,12 @@ async fn cmd_delete_folder( app_handle: AppHandle, window: WebviewWindow, folder_id: &str, -) -> Result { - delete_folder(&app_handle, folder_id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .delete_folder_by_id(folder_id, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1463,57 +1483,64 @@ async fn cmd_delete_environment( app_handle: AppHandle, window: WebviewWindow, environment_id: &str, -) -> Result { - delete_environment(&app_handle, environment_id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .delete_environment_by_id(environment_id, &UpdateSource::from_window(&window))?) } #[tauri::command] async fn cmd_list_grpc_connections( workspace_id: &str, app_handle: AppHandle, -) -> Result, String> { - list_grpc_connections_for_workspace(&app_handle, workspace_id).await.map_err(|e| e.to_string()) +) -> YaakResult> { + Ok(app_handle + .queries() + .connect() + .await? + .list_grpc_connections_for_workspace(workspace_id, None)?) } #[tauri::command] async fn cmd_list_grpc_events( connection_id: &str, app_handle: AppHandle, -) -> Result, String> { - list_grpc_events(&app_handle, connection_id).await.map_err(|e| e.to_string()) +) -> YaakResult> { + Ok(app_handle.queries().connect().await?.list_grpc_events(connection_id)?) } #[tauri::command] async fn cmd_list_grpc_requests( workspace_id: &str, app_handle: AppHandle, -) -> Result, String> { - list_grpc_requests(&app_handle, workspace_id).await.map_err(|e| e.to_string()) +) -> YaakResult> { + Ok(app_handle.queries().connect().await?.list_grpc_requests(workspace_id)?) } #[tauri::command] async fn cmd_list_http_requests( workspace_id: &str, app_handle: AppHandle, -) -> Result, String> { - list_http_requests(&app_handle, workspace_id).await.map_err(|e| e.to_string()) +) -> YaakResult> { + Ok(app_handle.queries().connect().await?.list_http_requests(workspace_id)?) } #[tauri::command] async fn cmd_list_environments( workspace_id: &str, app_handle: AppHandle, -) -> Result, String> { +) -> YaakResult> { // Not sure of a better place to put this... - ensure_base_environment(&app_handle, workspace_id).await.map_err(|e| e.to_string())?; - list_environments(&app_handle, workspace_id).await.map_err(|e| e.to_string()) + let db = app_handle.queries().connect().await?; + db.ensure_base_environment(workspace_id)?; + Ok(db.list_environments(workspace_id)?) } #[tauri::command] -async fn cmd_list_plugins(app_handle: AppHandle) -> Result, String> { - list_plugins(&app_handle).await.map_err(|e| e.to_string()) +async fn cmd_list_plugins(app_handle: AppHandle) -> YaakResult> { + Ok(app_handle.queries().connect().await?.list_plugins()?) } #[tauri::command] @@ -1534,19 +1561,23 @@ async fn cmd_plugin_info( id: &str, app_handle: AppHandle, plugin_manager: State<'_, PluginManager>, -) -> Result { - let plugin = get_plugin(&app_handle, id).await.map_err(|e| e.to_string())?; +) -> YaakResult { + let plugin = app_handle.queries().connect().await?.get_plugin(id)?; Ok(plugin_manager .get_plugin_by_dir(plugin.directory.as_str()) .await - .ok_or("Failed to find plugin for info".to_string())? + .ok_or(GenericError("Failed to find plugin for info".to_string()))? .info() .await) } #[tauri::command] -async fn cmd_get_settings(app_handle: AppHandle) -> Result { - Ok(get_or_create_settings(&app_handle).await) +async fn cmd_get_settings(window: WebviewWindow) -> YaakResult { + Ok(window + .queries() + .connect() + .await? + .get_or_create_settings(&UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1554,39 +1585,41 @@ async fn cmd_update_settings( settings: Settings, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - update_settings(&app_handle, settings, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .upsert_settings(&settings, &UpdateSource::from_window(&window))?) } #[tauri::command] -async fn cmd_get_folder(id: &str, app_handle: AppHandle) -> Result { - get_folder(&app_handle, id).await.map_err(|e| e.to_string()) +async fn cmd_get_folder(id: &str, app_handle: AppHandle) -> YaakResult { + Ok(app_handle.queries().connect().await?.get_folder(id)?) } #[tauri::command] async fn cmd_get_grpc_request( id: &str, app_handle: AppHandle, -) -> Result, String> { - get_grpc_request(&app_handle, id).await.map_err(|e| e.to_string()) +) -> YaakResult> { + Ok(app_handle.queries().connect().await?.get_grpc_request(id)?) } #[tauri::command] async fn cmd_get_http_request( id: &str, app_handle: AppHandle, -) -> Result, String> { - get_http_request(&app_handle, id).await.map_err(|e| e.to_string()) +) -> YaakResult> { + Ok(app_handle.queries().connect().await?.get_http_request(id)?) } #[tauri::command] async fn cmd_get_cookie_jar( id: &str, app_handle: AppHandle, -) -> Result { - get_cookie_jar(&app_handle, id).await.map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle.queries().connect().await?.get_cookie_jar(id)?) } #[tauri::command] @@ -1594,22 +1627,19 @@ async fn cmd_list_cookie_jars( workspace_id: &str, app_handle: AppHandle, window: WebviewWindow, -) -> Result, String> { - let cookie_jars = - list_cookie_jars(&app_handle, workspace_id).await.expect("Failed to find cookie jars"); +) -> YaakResult> { + let db = app_handle.queries().connect().await?; + let cookie_jars = db.list_cookie_jars(workspace_id)?; if cookie_jars.is_empty() { - let cookie_jar = upsert_cookie_jar( - &app_handle, + let cookie_jar = db.upsert_cookie_jar( &CookieJar { name: "Default".to_string(), workspace_id: workspace_id.to_string(), ..Default::default() }, &UpdateSource::from_window(&window), - ) - .await - .expect("Failed to create CookieJar"); + )?; Ok(vec![cookie_jar]) } else { Ok(cookie_jars) @@ -1617,26 +1647,24 @@ async fn cmd_list_cookie_jars( } #[tauri::command] -async fn cmd_list_key_values( - app_handle: AppHandle, -) -> Result, String> { - list_key_values_raw(&app_handle).await.map_err(|e| e.to_string()) +async fn cmd_list_key_values(app_handle: AppHandle) -> YaakResult> { + Ok(app_handle.queries().connect().await?.list_key_values_raw()?) } #[tauri::command] async fn cmd_get_environment( id: &str, app_handle: AppHandle, -) -> Result { - get_environment(&app_handle, id).await.map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle.queries().connect().await?.get_environment(id)?) } #[tauri::command] async fn cmd_get_workspace( id: &str, app_handle: AppHandle, -) -> Result { - get_workspace(&app_handle, id).await.map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle.queries().connect().await?.get_workspace(id)?) } #[tauri::command] @@ -1644,10 +1672,12 @@ async fn cmd_list_http_responses( workspace_id: &str, limit: Option, app_handle: AppHandle, -) -> Result, String> { - list_http_responses_for_workspace(&app_handle, workspace_id, limit) - .await - .map_err(|e| e.to_string()) +) -> YaakResult> { + Ok(app_handle + .queries() + .connect() + .await? + .list_http_responses_for_workspace(workspace_id, limit.map(|l| l as u64))?) } #[tauri::command] @@ -1655,10 +1685,10 @@ async fn cmd_delete_http_response( id: &str, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - delete_http_response(&app_handle, id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + let db = app_handle.queries().connect().await?; + let http_response = db.get_http_response(id)?; + Ok(db.delete_http_response(&http_response, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1666,10 +1696,12 @@ async fn cmd_delete_grpc_connection( id: &str, app_handle: AppHandle, window: WebviewWindow, -) -> Result { - delete_grpc_connection(&app_handle, id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .delete_grpc_connection_by_id(id, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1677,10 +1709,12 @@ async fn cmd_delete_all_grpc_connections( request_id: &str, app_handle: AppHandle, window: WebviewWindow, -) -> Result<(), String> { - delete_all_grpc_connections(&app_handle, request_id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult<()> { + Ok(app_handle + .queries() + .connect() + .await? + .delete_all_grpc_connections_for_request(request_id, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1688,29 +1722,17 @@ async fn cmd_delete_send_history( workspace_id: &str, app_handle: AppHandle, window: WebviewWindow, -) -> Result<(), String> { - delete_all_http_responses_for_workspace( - &app_handle, - workspace_id, - &UpdateSource::from_window(&window), - ) - .await - .map_err(|e| e.to_string())?; - delete_all_grpc_connections_for_workspace( - &app_handle, - workspace_id, - &UpdateSource::from_window(&window), - ) - .await - .map_err(|e| e.to_string())?; - delete_all_websocket_connections_for_workspace( - &app_handle, - workspace_id, - &UpdateSource::from_window(&window), - ) - .await - .map_err(|e| e.to_string())?; - Ok(()) +) -> YaakResult<()> { + Ok(app_handle + .queries() + .with_tx(|tx| { + let source = &UpdateSource::from_window(&window); + tx.delete_all_http_responses_for_workspace(workspace_id, source)?; + tx.delete_all_grpc_connections_for_workspace(workspace_id, source)?; + tx.delete_all_websocket_connections_for_workspace(workspace_id, source)?; + Ok(()) + }) + .await?) } #[tauri::command] @@ -1718,35 +1740,31 @@ async fn cmd_delete_all_http_responses( request_id: &str, app_handle: AppHandle, window: WebviewWindow, -) -> Result<(), String> { - delete_all_http_responses_for_request( - &app_handle, - request_id, - &UpdateSource::from_window(&window), - ) - .await - .map_err(|e| e.to_string()) +) -> YaakResult<()> { + Ok(app_handle + .queries() + .connect() + .await? + .delete_all_http_responses_for_request(request_id, &UpdateSource::from_window(&window))?) } #[tauri::command] async fn cmd_list_workspaces( app_handle: AppHandle, window: WebviewWindow, -) -> Result, String> { - let workspaces = list_workspaces(&app_handle).await.expect("Failed to find workspaces"); +) -> YaakResult> { + let queries = app_handle.queries().connect().await?; + let workspaces = queries.find_all::()?; if workspaces.is_empty() { - let workspace = upsert_workspace( - &app_handle, - Workspace { + let workspace = queries.upsert_workspace( + &Workspace { name: "Yaak".to_string(), setting_follow_redirects: true, setting_validate_certificates: true, ..Default::default() }, &UpdateSource::from_window(&window), - ) - .await - .expect("Failed to create Workspace"); + )?; Ok(vec![workspace]) } else { Ok(workspaces) @@ -1758,11 +1776,10 @@ async fn cmd_get_workspace_meta( app_handle: AppHandle, window: WebviewWindow, workspace_id: &str, -) -> Result { - let workspace = get_workspace(&app_handle, workspace_id).await.map_err(|e| e.to_string())?; - get_or_create_workspace_meta(&app_handle, &workspace, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + let db = app_handle.queries().connect().await?; + let workspace = db.get_workspace(workspace_id)?; + Ok(db.get_or_create_workspace_meta(&workspace, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -1788,24 +1805,21 @@ async fn cmd_delete_workspace( app_handle: AppHandle, window: WebviewWindow, workspace_id: &str, -) -> Result { - delete_workspace(&app_handle, workspace_id, &UpdateSource::from_window(&window)) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + Ok(app_handle + .queries() + .connect() + .await? + .delete_workspace_by_id(workspace_id, &UpdateSource::from_window(&window))?) } #[tauri::command] -async fn cmd_check_for_updates( - app_handle: AppHandle, +async fn cmd_check_for_updates( + window: WebviewWindow, yaak_updater: State<'_, Mutex>, -) -> Result { - let update_mode = get_update_mode(&app_handle).await; - yaak_updater - .lock() - .await - .check_now(&app_handle, update_mode, UpdateTrigger::User) - .await - .map_err(|e| e.to_string()) +) -> YaakResult { + let update_mode = get_update_mode(&window).await?; + Ok(yaak_updater.lock().await.check_now(&window, update_mode, UpdateTrigger::User).await?) } #[cfg_attr(mobile, tauri::mobile_entry_point)] @@ -1856,7 +1870,7 @@ pub fn run() { .plugin(tauri_plugin_os::init()) .plugin(tauri_plugin_fs::init()) .plugin(yaak_license::init()) - .plugin(yaak_models::plugin::Builder::default().build()) + .plugin(yaak_models::init()) .plugin(yaak_plugins::init()) .plugin(yaak_git::init()) .plugin(yaak_ws::init()) @@ -1895,7 +1909,6 @@ pub fn run() { cmd_create_cookie_jar, cmd_create_environment, cmd_create_grpc_request, - cmd_create_http_request, cmd_curl_to_request, cmd_delete_all_grpc_connections, cmd_delete_all_http_responses, @@ -1962,7 +1975,7 @@ pub fn run() { cmd_update_environment, cmd_update_folder, cmd_update_grpc_request, - cmd_update_http_request, + cmd_upsert_http_request, cmd_update_settings, cmd_update_workspace, cmd_update_workspace_meta, @@ -1983,21 +1996,24 @@ pub fn run() { // Cancel pending requests let h = app_handle.clone(); tauri::async_runtime::block_on(async move { - let _ = cancel_pending_http_responses(&h).await; - let _ = cancel_pending_grpc_connections(&h).await; - let _ = cancel_pending_websocket_connections(&h).await; + let db = h.queries().connect().await.unwrap(); + let _ = db.cancel_pending_http_responses(); + let _ = db.cancel_pending_grpc_connections(); + let _ = db.cancel_pending_websocket_connections(); }); } RunEvent::WindowEvent { event: WindowEvent::Focused(true), + label, .. } => { + let w = app_handle.get_webview_window(&label).unwrap(); let h = app_handle.clone(); - // Run update check whenever window is focused + // Run update check whenever the window is focused tauri::async_runtime::spawn(async move { let val: State<'_, Mutex> = h.state(); - let update_mode = get_update_mode(&h).await; - if let Err(e) = val.lock().await.maybe_check(&h, update_mode).await { + let update_mode = get_update_mode(&w).await.unwrap(); + if let Err(e) = val.lock().await.maybe_check(&w, update_mode).await { warn!("Failed to check for updates {e:?}"); }; }); @@ -2014,11 +2030,6 @@ pub fn run() { } }); } - _ => {} - }; - - // Save window state on exit - match event { RunEvent::WindowEvent { event: WindowEvent::CloseRequested { .. }, .. @@ -2034,9 +2045,13 @@ pub fn run() { }); } -async fn get_update_mode(h: &AppHandle) -> UpdateMode { - let settings = get_or_create_settings(h).await; - UpdateMode::new(settings.update_channel.as_str()) +async fn get_update_mode(window: &WebviewWindow) -> YaakResult { + let settings = window + .queries() + .connect() + .await? + .get_or_create_settings(&UpdateSource::from_window(window))?; + Ok(UpdateMode::new(settings.update_channel.as_str())) } fn safe_uri(endpoint: &str) -> String { @@ -2134,10 +2149,10 @@ fn workspace_id_from_window(window: &WebviewWindow) -> Option(window: &WebviewWindow) -> Option { +async fn workspace_from_window(window: &WebviewWindow) -> YaakResult { match workspace_id_from_window(&window) { - None => None, - Some(id) => get_workspace(window.app_handle(), id.as_str()).await.ok(), + None => Err(GenericError("Failed to get workspace ID from window".to_string())), + Some(id) => Ok(window.queries().connect().await?.get_workspace(id.as_str())?), } } @@ -2150,7 +2165,7 @@ fn environment_id_from_window(window: &WebviewWindow) -> Option(window: &WebviewWindow) -> Option { match environment_id_from_window(&window) { None => None, - Some(id) => get_environment(window.app_handle(), id.as_str()).await.ok(), + Some(id) => window.queries().connect().await.unwrap().get_environment(&id).ok(), } } @@ -2163,6 +2178,6 @@ fn cookie_jar_id_from_window(window: &WebviewWindow) -> Option(window: &WebviewWindow) -> Option { match cookie_jar_id_from_window(&window) { None => None, - Some(id) => get_cookie_jar(window.app_handle(), id.as_str()).await.ok(), + Some(id) => window.queries().connect().await.unwrap().get_cookie_jar(&id).ok(), } } diff --git a/src-tauri/src/notifications.rs b/src-tauri/src/notifications.rs index fc4a94a73..432f3cbc0 100644 --- a/src-tauri/src/notifications.rs +++ b/src-tauri/src/notifications.rs @@ -7,7 +7,8 @@ use reqwest::Method; use serde::{Deserialize, Serialize}; use serde_json::Value; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow}; -use yaak_models::queries::{get_key_value_raw, set_key_value_raw, UpdateSource}; +use yaak_models::manager::QueryManagerExt; +use yaak_models::queries_legacy::UpdateSource; // Check for updates every hour const MAX_UPDATE_CHECK_SECONDS: u64 = 60 * 60; @@ -43,13 +44,22 @@ impl YaakNotifier { } } - pub async fn seen(&mut self, window: &WebviewWindow, id: &str) -> Result<(), String> { + pub async fn seen( + &mut self, + window: &WebviewWindow, + id: &str, + ) -> Result<(), String> { let app_handle = window.app_handle(); let mut seen = get_kv(app_handle).await?; seen.push(id.to_string()); debug!("Marked notification as seen {}", id); let seen_json = serde_json::to_string(&seen).map_err(|e| e.to_string())?; - set_key_value_raw(app_handle, KV_NAMESPACE, KV_KEY, seen_json.as_str(), &UpdateSource::from_window(window)).await; + window.queries().connect().await.map_err(|e| e.to_string())?.set_key_value_raw( + KV_NAMESPACE, + KV_KEY, + seen_json.as_str(), + &UpdateSource::from_window(window), + ); Ok(()) } @@ -70,7 +80,7 @@ impl YaakNotifier { .query(&[ ("version", info.version.to_string().as_str()), ("launches", num_launches.to_string().as_str()), - ("platform", get_os()) + ("platform", get_os()), ]); let resp = req.send().await.map_err(|e| e.to_string())?; if resp.status() != 200 { @@ -108,7 +118,13 @@ impl YaakNotifier { } async fn get_kv(app_handle: &AppHandle) -> Result, String> { - match get_key_value_raw(app_handle, "notifications", "seen").await { + match app_handle + .queries() + .connect() + .await + .map_err(|e| e.to_string())? + .get_key_value_raw("notifications", "seen") + { None => Ok(Vec::new()), Some(v) => serde_json::from_str(&v.value).map_err(|e| e.to_string()), } diff --git a/src-tauri/src/plugin_events.rs b/src-tauri/src/plugin_events.rs index 5a680c461..952096390 100644 --- a/src-tauri/src/plugin_events.rs +++ b/src-tauri/src/plugin_events.rs @@ -9,12 +9,9 @@ use chrono::Utc; use log::warn; use tauri::{AppHandle, Emitter, Manager, Runtime, State}; use tauri_plugin_clipboard_manager::ClipboardExt; +use yaak_models::manager::QueryManagerExt; use yaak_models::models::{HttpResponse, Plugin}; -use yaak_models::queries::{ - create_default_http_response, delete_plugin_key_value, get_base_environment, get_http_request, - get_plugin_key_value, list_http_responses_for_request, list_plugins, set_plugin_key_value, - upsert_plugin, UpdateSource, -}; +use yaak_models::queries_legacy::UpdateSource; use yaak_plugins::events::{ Color, DeleteKeyValueResponse, EmptyPayload, FindHttpResponsesResponse, GetHttpRequestByIdResponse, GetKeyValueResponse, Icon, InternalEvent, InternalEventPayload, @@ -55,19 +52,28 @@ pub(crate) async fn handle_plugin_event( call_frontend(window, event).await } InternalEventPayload::FindHttpResponsesRequest(req) => { - let http_responses = list_http_responses_for_request( - app_handle, - req.request_id.as_str(), - req.limit.map(|l| l as i64), - ) - .await - .unwrap_or_default(); + let http_responses = app_handle + .queries() + .connect() + .await + .unwrap() + .list_http_responses_for_request( + req.request_id.as_str(), + req.limit.map(|l| l as u64), + ) + .unwrap_or_default(); Some(InternalEventPayload::FindHttpResponsesResponse(FindHttpResponsesResponse { http_responses, })) } InternalEventPayload::GetHttpRequestByIdRequest(req) => { - let http_request = get_http_request(app_handle, req.id.as_str()).await.unwrap(); + let http_request = app_handle + .queries() + .connect() + .await + .unwrap() + .get_http_request(req.id.as_str()) + .unwrap(); Some(InternalEventPayload::GetHttpRequestByIdResponse(GetHttpRequestByIdResponse { http_request, })) @@ -80,8 +86,12 @@ pub(crate) async fn handle_plugin_event( .await .expect("Failed to get workspace_id from window URL"); let environment = environment_from_window(&window).await; - let base_environment = get_base_environment(app_handle, workspace.id.as_str()) + let base_environment = app_handle + .queries() + .connect() .await + .unwrap() + .get_base_environment(&workspace.id) .expect("Failed to get base environment"); let cb = PluginTemplateCallback::new(app_handle, &window_context, req.purpose); let http_request = render_http_request( @@ -104,8 +114,12 @@ pub(crate) async fn handle_plugin_event( .await .expect("Failed to get workspace_id from window URL"); let environment = environment_from_window(&window).await; - let base_environment = get_base_environment(app_handle, workspace.id.as_str()) + let base_environment = app_handle + .queries() + .connect() .await + .unwrap() + .get_base_environment(&workspace.id) .expect("Failed to get base environment"); let cb = PluginTemplateCallback::new(app_handle, &window_context, req.purpose); let data = render_json_value(req.data, &base_environment, environment.as_ref(), &cb) @@ -135,7 +149,7 @@ pub(crate) async fn handle_plugin_event( InternalEventPayload::ReloadResponse(_) => { let window = get_window_from_window_context(app_handle, &window_context) .expect("Failed to find window for plugin reload"); - let plugins = list_plugins(app_handle).await.unwrap(); + let plugins = app_handle.queries().connect().await.unwrap().list_plugins().unwrap(); for plugin in plugins { if plugin.directory != plugin_handle.dir { continue; @@ -145,7 +159,13 @@ pub(crate) async fn handle_plugin_event( updated_at: Utc::now().naive_utc(), // TODO: Add reloaded_at field to use instead ..plugin }; - upsert_plugin(app_handle, new_plugin, &UpdateSource::Plugin).await.unwrap(); + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_plugin(&new_plugin, &UpdateSource::Plugin) + .unwrap(); } let toast_event = plugin_handle.build_event_to_send( &WindowContext::from_window(&window), @@ -173,22 +193,29 @@ pub(crate) async fn handle_plugin_event( http_request.workspace_id = workspace.id; } - let resp = if http_request.id.is_empty() { - HttpResponse::new() + let http_response = if http_request.id.is_empty() { + HttpResponse::default() } else { - create_default_http_response( - app_handle, - http_request.id.as_str(), - &UpdateSource::Plugin, - ) - .await - .unwrap() + window + .queries() + .connect() + .await + .unwrap() + .upsert_http_response( + &HttpResponse { + request_id: http_request.id.clone(), + workspace_id: http_request.workspace_id.clone(), + ..Default::default() + }, + &UpdateSource::Plugin, + ) + .unwrap() }; let result = send_http_request( &window, &http_request, - &resp, + &http_response, environment, cookie_jar, &mut tokio::sync::watch::channel(false).1, // No-op cancel channel @@ -265,17 +292,34 @@ pub(crate) async fn handle_plugin_event( } InternalEventPayload::SetKeyValueRequest(req) => { let name = plugin_handle.name().await; - set_plugin_key_value(app_handle, &name, &req.key, &req.value).await; + app_handle + .queries() + .connect() + .await + .unwrap() + .set_plugin_key_value(&name, &req.key, &req.value); Some(InternalEventPayload::SetKeyValueResponse(SetKeyValueResponse {})) } InternalEventPayload::GetKeyValueRequest(req) => { let name = plugin_handle.name().await; - let value = get_plugin_key_value(app_handle, &name, &req.key).await.map(|v| v.value); + let value = app_handle + .queries() + .connect() + .await + .unwrap() + .get_plugin_key_value(&name, &req.key) + .map(|v| v.value); Some(InternalEventPayload::GetKeyValueResponse(GetKeyValueResponse { value })) } InternalEventPayload::DeleteKeyValueRequest(req) => { let name = plugin_handle.name().await; - let deleted = delete_plugin_key_value(app_handle, &name, &req.key).await; + let deleted = app_handle + .queries() + .connect() + .await + .unwrap() + .delete_plugin_key_value(&name, &req.key) + .unwrap(); Some(InternalEventPayload::DeleteKeyValueResponse(DeleteKeyValueResponse { deleted })) } _ => None, diff --git a/src-tauri/src/updates.rs b/src-tauri/src/updates.rs index 8d108bae0..123b893ed 100644 --- a/src-tauri/src/updates.rs +++ b/src-tauri/src/updates.rs @@ -1,12 +1,14 @@ use std::fmt::{Display, Formatter}; use std::time::SystemTime; +use crate::error::Result; use log::info; -use tauri::{AppHandle, Manager}; +use tauri::{Manager, Runtime, WebviewWindow}; use tauri_plugin_dialog::{DialogExt, MessageDialogButtons}; use tauri_plugin_updater::UpdaterExt; use tokio::task::block_in_place; -use yaak_models::queries::get_or_create_settings; +use yaak_models::manager::QueryManagerExt; +use yaak_models::queries_legacy::UpdateSource; use yaak_plugins::manager::PluginManager; use crate::is_dev; @@ -59,30 +61,34 @@ impl YaakUpdater { } } - pub async fn check_now( + pub async fn check_now( &mut self, - app_handle: &AppHandle, + window: &WebviewWindow, mode: UpdateMode, update_trigger: UpdateTrigger, - ) -> Result { - let settings = get_or_create_settings(app_handle).await; + ) -> Result { + let settings = window + .queries() + .connect() + .await? + .get_or_create_settings(&UpdateSource::from_window(window))?; let update_key = format!("{:x}", md5::compute(settings.id)); self.last_update_check = SystemTime::now(); info!("Checking for updates mode={}", mode); - let h = app_handle.clone(); - let update_check_result = app_handle + let w = window.clone(); + let update_check_result = w .updater_builder() .on_before_exit(move || { // Kill plugin manager before exit or NSIS installer will fail to replace sidecar // while it's running. // NOTE: This is only called on Windows - let h = h.clone(); + let w = w.clone(); block_in_place(|| { tauri::async_runtime::block_on(async move { info!("Shutting down plugin manager before update"); - let plugin_manager = h.state::(); + let plugin_manager = w.state::(); plugin_manager.terminate().await; }); }); @@ -100,11 +106,11 @@ impl YaakUpdater { .check() .await; - match update_check_result { - Ok(Some(update)) => { - let h = app_handle.clone(); - app_handle - .dialog() + let result = match update_check_result? { + None => false, + Some(update) => { + let w = window.clone(); + w.dialog() .message(format!( "{} is available. Would you like to download and install it now?", update.version @@ -121,7 +127,7 @@ impl YaakUpdater { tauri::async_runtime::spawn(async move { match update.download_and_install(|_, _| {}, || {}).await { Ok(_) => { - if h.dialog() + if w.dialog() .message("Would you like to restart the app?") .title("Update Installed") .buttons(MessageDialogButtons::OkCancelCustom( @@ -130,27 +136,27 @@ impl YaakUpdater { )) .blocking_show() { - h.restart(); + w.app_handle().restart(); } } Err(e) => { - h.dialog() + w.dialog() .message(format!("The update failed to install: {}", e)); } } }); }); - Ok(true) + true } - Ok(None) => Ok(false), - Err(e) => Err(e), - } + }; + + Ok(result) } - pub async fn maybe_check( + pub async fn maybe_check( &mut self, - app_handle: &AppHandle, + window: &WebviewWindow, mode: UpdateMode, - ) -> Result { + ) -> Result { let update_period_seconds = match mode { UpdateMode::Stable => MAX_UPDATE_CHECK_HOURS_STABLE, UpdateMode::Beta => MAX_UPDATE_CHECK_HOURS_BETA, @@ -167,6 +173,6 @@ impl YaakUpdater { return Ok(false); } - self.check_now(app_handle, mode, UpdateTrigger::Background).await + self.check_now(window, mode, UpdateTrigger::Background).await } } diff --git a/src-tauri/yaak-git/Cargo.toml b/src-tauri/yaak-git/Cargo.toml index 65afd9733..28dc1bbc4 100644 --- a/src-tauri/yaak-git/Cargo.toml +++ b/src-tauri/yaak-git/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] chrono = { version = "0.4.38", features = ["serde"] } -git2 = { version = "0.20.0" , features = ["vendored-libgit2", "vendored-openssl"]} +git2 = { version = "0.20.0", features = ["vendored-libgit2", "vendored-openssl"] } log = "0.4.22" serde = { version = "1.0.215", features = ["derive"] } serde_json = "1.0.132" @@ -19,4 +19,4 @@ yaak-models = { workspace = true } yaak-sync = { workspace = true } [build-dependencies] -tauri-plugin = { version = "2.0.3", features = ["build"] } +tauri-plugin = { workspace = true, features = ["build"] } diff --git a/src-tauri/yaak-git/permissions/schemas/schema.json b/src-tauri/yaak-git/permissions/schemas/schema.json index e7b50e708..b996cc212 100644 --- a/src-tauri/yaak-git/permissions/schemas/schema.json +++ b/src-tauri/yaak-git/permissions/schemas/schema.json @@ -49,7 +49,7 @@ "minimum": 1.0 }, "description": { - "description": "Human-readable description of what the permission does. Tauri convention is to use

headings in markdown content for Tauri documentation generation purposes.", + "description": "Human-readable description of what the permission does. Tauri convention is to use `

` headings in markdown content for Tauri documentation generation purposes.", "type": [ "string", "null" @@ -111,7 +111,7 @@ "type": "string" }, "description": { - "description": "Human-readable description of what the permission does. Tauri internal convention is to use

headings in markdown content for Tauri documentation generation purposes.", + "description": "Human-readable description of what the permission does. Tauri internal convention is to use `

` headings in markdown content for Tauri documentation generation purposes.", "type": [ "string", "null" diff --git a/src-tauri/yaak-license/permissions/schemas/schema.json b/src-tauri/yaak-license/permissions/schemas/schema.json index 3071b1109..f4a272bb5 100644 --- a/src-tauri/yaak-license/permissions/schemas/schema.json +++ b/src-tauri/yaak-license/permissions/schemas/schema.json @@ -49,7 +49,7 @@ "minimum": 1.0 }, "description": { - "description": "Human-readable description of what the permission does. Tauri convention is to use

headings in markdown content for Tauri documentation generation purposes.", + "description": "Human-readable description of what the permission does. Tauri convention is to use `

` headings in markdown content for Tauri documentation generation purposes.", "type": [ "string", "null" @@ -111,7 +111,7 @@ "type": "string" }, "description": { - "description": "Human-readable description of what the permission does. Tauri internal convention is to use

headings in markdown content for Tauri documentation generation purposes.", + "description": "Human-readable description of what the permission does. Tauri internal convention is to use `

` headings in markdown content for Tauri documentation generation purposes.", "type": [ "string", "null" diff --git a/src-tauri/yaak-license/src/commands.rs b/src-tauri/yaak-license/src/commands.rs index aadf268d2..ced67c969 100644 --- a/src-tauri/yaak-license/src/commands.rs +++ b/src-tauri/yaak-license/src/commands.rs @@ -5,16 +5,16 @@ use crate::{ }; use log::{debug, info}; use std::string::ToString; -use tauri::{command, AppHandle, Manager, Runtime, WebviewWindow}; +use tauri::{command, Manager, Runtime, WebviewWindow}; #[command] -pub async fn check(app_handle: AppHandle) -> Result { +pub async fn check(window: WebviewWindow) -> Result { debug!("Checking license"); check_license( - &app_handle, + &window, CheckActivationRequestPayload { app_platform: get_os().to_string(), - app_version: app_handle.package_info().version.to_string(), + app_version: window.package_info().version.to_string(), }, ) .await diff --git a/src-tauri/yaak-license/src/error.rs b/src-tauri/yaak-license/src/error.rs index e48f57b40..817926904 100644 --- a/src-tauri/yaak-license/src/error.rs +++ b/src-tauri/yaak-license/src/error.rs @@ -12,6 +12,9 @@ pub enum Error { #[error("{message}")] ClientError { message: String, error: String }, + #[error(transparent)] + ModelError(#[from] yaak_models::error::Error), + #[error("Internal server error")] ServerError, } diff --git a/src-tauri/yaak-license/src/license.rs b/src-tauri/yaak-license/src/license.rs index e5b2b8efd..c7e512bce 100644 --- a/src-tauri/yaak-license/src/license.rs +++ b/src-tauri/yaak-license/src/license.rs @@ -7,7 +7,8 @@ use std::ops::Add; use std::time::Duration; use tauri::{is_dev, AppHandle, Emitter, Manager, Runtime, WebviewWindow}; use ts_rs::TS; -use yaak_models::queries::UpdateSource; +use yaak_models::manager::QueryManagerExt; +use yaak_models::queries_legacy::UpdateSource; const KV_NAMESPACE: &str = "license"; const KV_ACTIVATION_ID_KEY: &str = "activation_id"; @@ -80,14 +81,12 @@ pub async fn activate_license( } let body: ActivateLicenseResponsePayload = response.json().await?; - yaak_models::queries::set_key_value_string( - window.app_handle(), + window.app_handle().queries().connect().await?.set_key_value_string( KV_ACTIVATION_ID_KEY, KV_NAMESPACE, body.activation_id.as_str(), &UpdateSource::from_window(&window), - ) - .await; + ); if let Err(e) = window.emit("license-activated", true) { warn!("Failed to emit check-license event: {}", e); @@ -119,13 +118,11 @@ pub async fn deactivate_license( return Err(ServerError); } - yaak_models::queries::delete_key_value( - app_handle, + app_handle.queries().connect().await?.delete_key_value( KV_ACTIVATION_ID_KEY, KV_NAMESPACE, &UpdateSource::from_window(&window), - ) - .await; + )?; if let Err(e) = app_handle.emit("license-deactivated", true) { warn!("Failed to emit deactivate-license event: {}", e); @@ -145,11 +142,15 @@ pub enum LicenseCheckStatus { } pub async fn check_license( - app_handle: &AppHandle, + window: &WebviewWindow, payload: CheckActivationRequestPayload, ) -> Result { - let activation_id = get_activation_id(app_handle).await; - let settings = yaak_models::queries::get_or_create_settings(app_handle).await; + let activation_id = get_activation_id(window.app_handle()).await; + let settings = window + .queries() + .connect() + .await? + .get_or_create_settings(&UpdateSource::from_window(window))?; let trial_end = settings.created_at.add(Duration::from_secs(TRIAL_SECONDS)); debug!("Trial ending at {trial_end:?}"); @@ -200,6 +201,9 @@ fn build_url(path: &str) -> String { } pub async fn get_activation_id(app_handle: &AppHandle) -> String { - yaak_models::queries::get_key_value_string(app_handle, KV_ACTIVATION_ID_KEY, KV_NAMESPACE, "") - .await + app_handle.queries().connect().await.unwrap().get_key_value_string( + KV_ACTIVATION_ID_KEY, + KV_NAMESPACE, + "", + ) } diff --git a/src-tauri/yaak-models/Cargo.toml b/src-tauri/yaak-models/Cargo.toml index 60f063524..8a7c5898c 100644 --- a/src-tauri/yaak-models/Cargo.toml +++ b/src-tauri/yaak-models/Cargo.toml @@ -1,5 +1,6 @@ [package] name = "yaak-models" +links = "yaak-models" version = "0.1.0" edition = "2021" publish = false @@ -18,4 +19,8 @@ serde_json = "1.0.122" sqlx = { version = "0.8.0", default-features = false, features = ["migrate", "sqlite", "runtime-tokio-rustls"] } tauri = { workspace = true } thiserror = "2.0.11" +tokio = "1.43.0" ts-rs = { workspace = true, features = ["chrono-impl", "serde-json-impl"] } + +[build-dependencies] +tauri-plugin = { workspace = true, features = ["build"] } diff --git a/src-tauri/yaak-models/bindings/gen_models.ts b/src-tauri/yaak-models/bindings/gen_models.ts index c42af1e8d..6cb2a62a8 100644 --- a/src-tauri/yaak-models/bindings/gen_models.ts +++ b/src-tauri/yaak-models/bindings/gen_models.ts @@ -1,6 +1,6 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type AnyModel = CookieJar | Environment | Folder | GrpcConnection | GrpcEvent | GrpcRequest | HttpRequest | HttpResponse | Plugin | Settings | KeyValue | Workspace | WorkspaceMeta | WebsocketConnection | WebsocketEvent | WebsocketRequest; +export type AnyModel = CookieJar | Environment | Folder | GrpcConnection | GrpcEvent | GrpcRequest | HttpRequest | HttpResponse | KeyValue | Plugin | Settings | SyncState | WebsocketConnection | WebsocketEvent | WebsocketRequest | Workspace | WorkspaceMeta; export type Cookie = { raw_cookie: string, domain: CookieDomain, expires: CookieExpires, path: [string, boolean], }; @@ -44,7 +44,9 @@ export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, export type KeyValue = { model: "key_value", createdAt: string, updatedAt: string, key: string, namespace: string, value: string, }; -export type ModelPayload = { model: AnyModel, updateSource: UpdateSource, }; +export type ModelChangeEvent = { "type": "upsert" } | { "type": "delete" }; + +export type ModelPayload = { model: AnyModel, updateSource: UpdateSource, change: ModelChangeEvent, }; export type Plugin = { model: "plugin", id: string, createdAt: string, updatedAt: string, checkedAt: string | null, directory: string, enabled: boolean, url: string | null, }; @@ -56,8 +58,6 @@ export type ProxySettingAuth = { user: string, password: string, }; export type Settings = { model: "settings", id: string, createdAt: string, updatedAt: string, appearance: string, editorFontSize: number, editorSoftWrap: boolean, interfaceFontSize: number, interfaceScale: number, openWorkspaceNewWindow: boolean | null, proxy: ProxySetting | null, theme: string, themeDark: string, themeLight: string, updateChannel: string, editorKeymap: EditorKeymap, }; -export type SyncHistory = { model: "sync_history", id: string, workspaceId: string, createdAt: string, states: Array, checksum: string, relPath: string, syncDir: string, }; - export type SyncState = { model: "sync_state", id: string, workspaceId: string, createdAt: string, updatedAt: string, flushedAt: string, modelId: string, checksum: string, relPath: string, syncDir: string, }; export type UpdateSource = { "type": "sync" } | { "type": "window", label: string, } | { "type": "plugin" } | { "type": "background" } | { "type": "import" }; diff --git a/src-tauri/yaak-models/build.rs b/src-tauri/yaak-models/build.rs new file mode 100644 index 000000000..12b6b5249 --- /dev/null +++ b/src-tauri/yaak-models/build.rs @@ -0,0 +1,5 @@ +const COMMANDS: &[&str] = &["upsert", "delete"]; + +fn main() { + tauri_plugin::Builder::new(COMMANDS).build(); +} diff --git a/src-tauri/yaak-models/permissions/autogenerated/commands/delete.toml b/src-tauri/yaak-models/permissions/autogenerated/commands/delete.toml new file mode 100644 index 000000000..3d9d52344 --- /dev/null +++ b/src-tauri/yaak-models/permissions/autogenerated/commands/delete.toml @@ -0,0 +1,13 @@ +# Automatically generated - DO NOT EDIT! + +"$schema" = "../../schemas/schema.json" + +[[permission]] +identifier = "allow-delete" +description = "Enables the delete command without any pre-configured scope." +commands.allow = ["delete"] + +[[permission]] +identifier = "deny-delete" +description = "Denies the delete command without any pre-configured scope." +commands.deny = ["delete"] diff --git a/src-tauri/yaak-models/permissions/autogenerated/commands/delete_model.toml b/src-tauri/yaak-models/permissions/autogenerated/commands/delete_model.toml new file mode 100644 index 000000000..0e8a51fbb --- /dev/null +++ b/src-tauri/yaak-models/permissions/autogenerated/commands/delete_model.toml @@ -0,0 +1,13 @@ +# Automatically generated - DO NOT EDIT! + +"$schema" = "../../schemas/schema.json" + +[[permission]] +identifier = "allow-delete-model" +description = "Enables the delete_model command without any pre-configured scope." +commands.allow = ["delete_model"] + +[[permission]] +identifier = "deny-delete-model" +description = "Denies the delete_model command without any pre-configured scope." +commands.deny = ["delete_model"] diff --git a/src-tauri/yaak-models/permissions/autogenerated/commands/upsert.toml b/src-tauri/yaak-models/permissions/autogenerated/commands/upsert.toml new file mode 100644 index 000000000..ea6fff09b --- /dev/null +++ b/src-tauri/yaak-models/permissions/autogenerated/commands/upsert.toml @@ -0,0 +1,13 @@ +# Automatically generated - DO NOT EDIT! + +"$schema" = "../../schemas/schema.json" + +[[permission]] +identifier = "allow-upsert" +description = "Enables the upsert command without any pre-configured scope." +commands.allow = ["upsert"] + +[[permission]] +identifier = "deny-upsert" +description = "Denies the upsert command without any pre-configured scope." +commands.deny = ["upsert"] diff --git a/src-tauri/yaak-models/permissions/autogenerated/commands/upsert_model.toml b/src-tauri/yaak-models/permissions/autogenerated/commands/upsert_model.toml new file mode 100644 index 000000000..369382e7f --- /dev/null +++ b/src-tauri/yaak-models/permissions/autogenerated/commands/upsert_model.toml @@ -0,0 +1,13 @@ +# Automatically generated - DO NOT EDIT! + +"$schema" = "../../schemas/schema.json" + +[[permission]] +identifier = "allow-upsert-model" +description = "Enables the upsert_model command without any pre-configured scope." +commands.allow = ["upsert_model"] + +[[permission]] +identifier = "deny-upsert-model" +description = "Denies the upsert_model command without any pre-configured scope." +commands.deny = ["upsert_model"] diff --git a/src-tauri/yaak-models/permissions/autogenerated/reference.md b/src-tauri/yaak-models/permissions/autogenerated/reference.md new file mode 100644 index 000000000..4b321b3a4 --- /dev/null +++ b/src-tauri/yaak-models/permissions/autogenerated/reference.md @@ -0,0 +1,120 @@ +## Default Permission + +Default permissions for the plugin + +- `allow-upsert` +- `allow-delete` + +## Permission Table + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IdentifierDescription
+ +`yaak-models:allow-delete` + + + +Enables the delete command without any pre-configured scope. + +
+ +`yaak-models:deny-delete` + + + +Denies the delete command without any pre-configured scope. + +
+ +`yaak-models:allow-delete-model` + + + +Enables the delete_model command without any pre-configured scope. + +
+ +`yaak-models:deny-delete-model` + + + +Denies the delete_model command without any pre-configured scope. + +
+ +`yaak-models:allow-upsert` + + + +Enables the upsert command without any pre-configured scope. + +
+ +`yaak-models:deny-upsert` + + + +Denies the upsert command without any pre-configured scope. + +
+ +`yaak-models:allow-upsert-model` + + + +Enables the upsert_model command without any pre-configured scope. + +
+ +`yaak-models:deny-upsert-model` + + + +Denies the upsert_model command without any pre-configured scope. + +
diff --git a/src-tauri/yaak-models/permissions/default.toml b/src-tauri/yaak-models/permissions/default.toml new file mode 100644 index 000000000..5a93edfb5 --- /dev/null +++ b/src-tauri/yaak-models/permissions/default.toml @@ -0,0 +1,6 @@ +[default] +description = "Default permissions for the plugin" +permissions = [ + "allow-upsert", + "allow-delete", +] diff --git a/src-tauri/yaak-models/permissions/schemas/schema.json b/src-tauri/yaak-models/permissions/schemas/schema.json new file mode 100644 index 000000000..8a9f675e2 --- /dev/null +++ b/src-tauri/yaak-models/permissions/schemas/schema.json @@ -0,0 +1,345 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PermissionFile", + "description": "Permission file that can define a default permission, a set of permissions or a list of inlined permissions.", + "type": "object", + "properties": { + "default": { + "description": "The default permission set for the plugin", + "anyOf": [ + { + "$ref": "#/definitions/DefaultPermission" + }, + { + "type": "null" + } + ] + }, + "set": { + "description": "A list of permissions sets defined", + "type": "array", + "items": { + "$ref": "#/definitions/PermissionSet" + } + }, + "permission": { + "description": "A list of inlined permissions", + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/Permission" + } + } + }, + "definitions": { + "DefaultPermission": { + "description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.", + "type": "object", + "required": [ + "permissions" + ], + "properties": { + "version": { + "description": "The version of the permission.", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 1.0 + }, + "description": { + "description": "Human-readable description of what the permission does. Tauri convention is to use `

` headings in markdown content for Tauri documentation generation purposes.", + "type": [ + "string", + "null" + ] + }, + "permissions": { + "description": "All permissions this set contains.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "PermissionSet": { + "description": "A set of direct permissions grouped together under a new name.", + "type": "object", + "required": [ + "description", + "identifier", + "permissions" + ], + "properties": { + "identifier": { + "description": "A unique identifier for the permission.", + "type": "string" + }, + "description": { + "description": "Human-readable description of what the permission does.", + "type": "string" + }, + "permissions": { + "description": "All permissions this set contains.", + "type": "array", + "items": { + "$ref": "#/definitions/PermissionKind" + } + } + } + }, + "Permission": { + "description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.", + "type": "object", + "required": [ + "identifier" + ], + "properties": { + "version": { + "description": "The version of the permission.", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 1.0 + }, + "identifier": { + "description": "A unique identifier for the permission.", + "type": "string" + }, + "description": { + "description": "Human-readable description of what the permission does. Tauri internal convention is to use `

` headings in markdown content for Tauri documentation generation purposes.", + "type": [ + "string", + "null" + ] + }, + "commands": { + "description": "Allowed or denied commands when using this permission.", + "default": { + "allow": [], + "deny": [] + }, + "allOf": [ + { + "$ref": "#/definitions/Commands" + } + ] + }, + "scope": { + "description": "Allowed or denied scoped when using this permission.", + "allOf": [ + { + "$ref": "#/definitions/Scopes" + } + ] + }, + "platforms": { + "description": "Target platforms this permission applies. By default all platforms are affected by this permission.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Target" + } + } + } + }, + "Commands": { + "description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.", + "type": "object", + "properties": { + "allow": { + "description": "Allowed command.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "deny": { + "description": "Denied command, which takes priority.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "Scopes": { + "description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json { \"allow\": [{ \"path\": \"$HOME/**\" }], \"deny\": [{ \"path\": \"$HOME/secret.txt\" }] } ```", + "type": "object", + "properties": { + "allow": { + "description": "Data that defines what is allowed by the scope.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Value" + } + }, + "deny": { + "description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Value" + } + } + } + }, + "Value": { + "description": "All supported ACL values.", + "anyOf": [ + { + "description": "Represents a null JSON value.", + "type": "null" + }, + { + "description": "Represents a [`bool`].", + "type": "boolean" + }, + { + "description": "Represents a valid ACL [`Number`].", + "allOf": [ + { + "$ref": "#/definitions/Number" + } + ] + }, + { + "description": "Represents a [`String`].", + "type": "string" + }, + { + "description": "Represents a list of other [`Value`]s.", + "type": "array", + "items": { + "$ref": "#/definitions/Value" + } + }, + { + "description": "Represents a map of [`String`] keys to [`Value`]s.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Value" + } + } + ] + }, + "Number": { + "description": "A valid ACL number.", + "anyOf": [ + { + "description": "Represents an [`i64`].", + "type": "integer", + "format": "int64" + }, + { + "description": "Represents a [`f64`].", + "type": "number", + "format": "double" + } + ] + }, + "Target": { + "description": "Platform target.", + "oneOf": [ + { + "description": "MacOS.", + "type": "string", + "enum": [ + "macOS" + ] + }, + { + "description": "Windows.", + "type": "string", + "enum": [ + "windows" + ] + }, + { + "description": "Linux.", + "type": "string", + "enum": [ + "linux" + ] + }, + { + "description": "Android.", + "type": "string", + "enum": [ + "android" + ] + }, + { + "description": "iOS.", + "type": "string", + "enum": [ + "iOS" + ] + } + ] + }, + "PermissionKind": { + "type": "string", + "oneOf": [ + { + "description": "Enables the delete command without any pre-configured scope.", + "type": "string", + "const": "allow-delete" + }, + { + "description": "Denies the delete command without any pre-configured scope.", + "type": "string", + "const": "deny-delete" + }, + { + "description": "Enables the delete_model command without any pre-configured scope.", + "type": "string", + "const": "allow-delete-model" + }, + { + "description": "Denies the delete_model command without any pre-configured scope.", + "type": "string", + "const": "deny-delete-model" + }, + { + "description": "Enables the upsert command without any pre-configured scope.", + "type": "string", + "const": "allow-upsert" + }, + { + "description": "Denies the upsert command without any pre-configured scope.", + "type": "string", + "const": "deny-upsert" + }, + { + "description": "Enables the upsert_model command without any pre-configured scope.", + "type": "string", + "const": "allow-upsert-model" + }, + { + "description": "Denies the upsert_model command without any pre-configured scope.", + "type": "string", + "const": "deny-upsert-model" + }, + { + "description": "Default permissions for the plugin", + "type": "string", + "const": "default" + } + ] + } + } +} \ No newline at end of file diff --git a/src-tauri/yaak-models/src/commands.rs b/src-tauri/yaak-models/src/commands.rs new file mode 100644 index 000000000..a0d597502 --- /dev/null +++ b/src-tauri/yaak-models/src/commands.rs @@ -0,0 +1,24 @@ +use crate::error::Result; +use crate::manager::QueryManagerExt; +use crate::models::AnyModel; +use crate::queries_legacy::UpdateSource; +use tauri::{Runtime, WebviewWindow}; + +#[tauri::command] +pub(crate) async fn upsert( + window: WebviewWindow, + model: AnyModel, +) -> Result { + let queries = window.queries().connect().await?; + let id = match model { + AnyModel::HttpRequest(r) => queries.upsert(&r, &UpdateSource::from_window(&window))?.id, + _ => todo!(), + }; + + Ok(id) +} + +#[tauri::command] +pub(crate) fn delete() -> Result<()> { + Ok(()) +} diff --git a/src-tauri/yaak-models/src/error.rs b/src-tauri/yaak-models/src/error.rs index 27f693f92..4fc6e030a 100644 --- a/src-tauri/yaak-models/src/error.rs +++ b/src-tauri/yaak-models/src/error.rs @@ -1,3 +1,4 @@ +use serde::{Serialize, Serializer}; use thiserror::Error; #[derive(Error, Debug)] @@ -11,11 +12,29 @@ pub enum Error { #[error("JSON error: {0}")] JsonError(#[from] serde_json::Error), - #[error("Model not found {0}")] + #[error("Model not found: {0}")] ModelNotFound(String), + #[error("Model serialization error: {0}")] + ModelSerializationError(String), + + #[error("Model error: {0}")] + GenericError(String), + + #[error("Row not found")] + RowNotFound, + #[error("unknown error")] Unknown, } +impl Serialize for Error { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: Serializer, + { + serializer.serialize_str(self.to_string().as_ref()) + } +} + pub type Result = std::result::Result; diff --git a/src-tauri/yaak-models/src/lib.rs b/src-tauri/yaak-models/src/lib.rs index 1b4b1ee7b..8d12790f1 100644 --- a/src-tauri/yaak-models/src/lib.rs +++ b/src-tauri/yaak-models/src/lib.rs @@ -1,7 +1,98 @@ +use crate::commands::{delete, upsert}; +use crate::manager::QueryManager; +use crate::queries_legacy::ModelChangeEvent; +use log::info; +use r2d2::Pool; +use r2d2_sqlite::SqliteConnectionManager; +use sqlx::migrate::Migrator; +use sqlx::sqlite::SqliteConnectOptions; +use sqlx::SqlitePool; +use std::fs::create_dir_all; +use std::path::PathBuf; +use std::str::FromStr; +use std::time::Duration; +use tauri::async_runtime::Mutex; +use tauri::path::BaseDirectory; +use tauri::plugin::TauriPlugin; +use tauri::{generate_handler, AppHandle, Emitter, Manager, Runtime}; +use tokio::sync::mpsc; + +mod commands; + pub mod error; +pub mod manager; pub mod models; pub mod queries; - -pub mod plugin; +pub mod queries_legacy; pub mod render; -pub mod manager; + +pub struct SqliteConnection(pub Mutex>); + +impl SqliteConnection { + pub(crate) fn new(pool: Pool) -> Self { + Self(Mutex::new(pool)) + } +} + +pub fn init() -> TauriPlugin { + tauri::plugin::Builder::new("yaak_models") + .invoke_handler(generate_handler![upsert, delete]) + .setup(|app_handle, _api| { + let app_path = app_handle.path().app_data_dir().unwrap(); + create_dir_all(app_path.clone()).expect("Problem creating App directory!"); + + let db_file_path = app_path.join("db.sqlite"); + + { + let db_file_path = db_file_path.clone(); + tauri::async_runtime::block_on(async move { + must_migrate_db(app_handle.app_handle(), &db_file_path).await; + }); + }; + + let manager = SqliteConnectionManager::file(db_file_path); + let pool = Pool::builder() + .max_size(100) // Up from 10 (just in case) + .connection_timeout(Duration::from_secs(10)) // Down from 30 + .build(manager) + .unwrap(); + + app_handle.manage(SqliteConnection::new(pool.clone())); + + { + let (tx, mut rx) = mpsc::channel(128); + app_handle.manage(QueryManager::new(pool, tx)); + let app_handle = app_handle.clone(); + tauri::async_runtime::spawn(async move { + while let Some(p) = rx.recv().await { + let name = match p.change { + ModelChangeEvent::Upsert => "upserted_model", + ModelChangeEvent::Delete => "deleted_model", + }; + app_handle.emit(name, p).unwrap(); + } + }); + } + + Ok(()) + }) + .build() +} + +async fn must_migrate_db(app_handle: &AppHandle, sqlite_file_path: &PathBuf) { + info!("Connecting to database at {sqlite_file_path:?}"); + let sqlite_file_path = sqlite_file_path.to_str().unwrap().to_string(); + let opts = SqliteConnectOptions::from_str(&sqlite_file_path).unwrap().create_if_missing(true); + let pool = SqlitePool::connect_with(opts).await.expect("Failed to connect to database"); + let p = app_handle + .path() + .resolve("migrations", BaseDirectory::Resource) + .expect("failed to resolve resource"); + + info!("Running database migrations from: {}", p.to_string_lossy()); + let mut m = Migrator::new(p).await.expect("Failed to load migrations"); + m.set_ignore_missing(true); // So we can roll back versions and not crash + m.run(&pool).await.expect("Failed to run migrations"); + + info!("Database migrations complete"); +} diff --git a/src-tauri/yaak-models/src/manager.rs b/src-tauri/yaak-models/src/manager.rs index 4da711611..de0f7693a 100644 --- a/src-tauri/yaak-models/src/manager.rs +++ b/src-tauri/yaak-models/src/manager.rs @@ -1,40 +1,108 @@ use crate::error::Result; -use crate::models::{Workspace, WorkspaceIden}; -use crate::plugin::SqliteConnection; +use crate::queries_legacy::ModelPayload; use r2d2::{Pool, PooledConnection}; use r2d2_sqlite::SqliteConnectionManager; -use rusqlite::Connection; -use sea_query::{Asterisk, Order, Query, SqliteQueryBuilder}; -use sea_query_rusqlite::RusqliteBinder; -use std::future::Future; -use std::ops::Deref; -use tauri::{AppHandle, Manager, Runtime}; +use rusqlite::{Connection, Statement, ToSql, Transaction, TransactionBehavior}; +use std::sync::Arc; +use tauri::{Manager, Runtime}; +use tokio::sync::{mpsc, Mutex}; +pub trait QueryManagerExt<'a, R> { + fn queries(&'a self) -> &'a QueryManager; +} + +impl<'a, R: Runtime, T: Manager> QueryManagerExt<'a, R> for T { + fn queries(&'a self) -> &'a QueryManager { + let qm = self.state::(); + qm.inner() + } +} + +#[derive(Clone)] pub struct QueryManager { - pool: Pool, + pool: Arc>>, + events_tx: mpsc::Sender, +} + +impl QueryManager { + pub(crate) fn new( + pool: Pool, + events_tx: mpsc::Sender, + ) -> Self { + QueryManager { + pool: Arc::new(Mutex::new(pool)), + events_tx, + } + } + + pub async fn connect(&self) -> Result { + let conn = self.pool.lock().await.get()?; + Ok(DbContext { + tx: self.events_tx.clone(), + conn: ConnectionOrTx::Connection(conn), + }) + } + + pub async fn with_conn(&self, func: F) -> Result + where + F: FnOnce(&DbContext) -> Result, + { + let conn = self.pool.lock().await.get()?; + let db_context = DbContext { + tx: self.events_tx.clone(), + conn: ConnectionOrTx::Connection(conn), + }; + func(&db_context) + } + + pub async fn with_tx(&self, func: F) -> Result + where + F: FnOnce(&DbContext) -> Result, + { + let mut conn = self.pool.lock().await.get()?; + let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate)?; + + let db_context = DbContext { + tx: self.events_tx.clone(), + conn: ConnectionOrTx::Transaction(&tx), + }; + + match func(&db_context) { + Ok(val) => { + tx.commit()?; + Ok(val) + } + Err(e) => { + tx.rollback()?; + Err(e) + } + } + } } -pub trait DBConnection { - fn connect( - &self, - ) -> impl Future>> + Send; +pub enum ConnectionOrTx<'a> { + Connection(PooledConnection), + Transaction(&'a Transaction<'a>), } -impl DBConnection for AppHandle { - async fn connect(&self) -> Result> { - let dbm = &*self.state::(); - let db = dbm.0.lock().await.get()?; - Ok(db) +impl<'a> ConnectionOrTx<'a> { + pub(crate) fn resolve(&self) -> &Connection { + match self { + ConnectionOrTx::Connection(c) => c, + ConnectionOrTx::Transaction(c) => c, + } + } + + pub(crate) fn prepare(&self, sql: &str) -> rusqlite::Result> { + self.resolve().prepare(sql) + } + + pub(crate) fn execute(&self, sql: &str, params: &[&dyn ToSql]) -> rusqlite::Result { + self.resolve().execute(sql, params) } } -pub async fn list_workspaces>(c: &T) -> Result> { - let (sql, params) = Query::select() - .from(WorkspaceIden::Table) - .column(Asterisk) - .order_by(WorkspaceIden::Name, Order::Asc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = c.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) +pub struct DbContext<'a> { + pub(crate) tx: mpsc::Sender, + pub(crate) conn: ConnectionOrTx<'a>, } diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index 0d266e725..cd8cbdcda 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -1,6 +1,12 @@ -use chrono::NaiveDateTime; +use crate::error::Result; +use crate::models::HttpRequestIden::{ + Authentication, AuthenticationType, Body, BodyType, CreatedAt, Description, FolderId, Headers, + Method, Name, SortPriority, UpdatedAt, Url, UrlParameters, WorkspaceId, +}; +use crate::queries_legacy::{generate_model_id, UpdateSource}; +use chrono::{NaiveDateTime, Utc}; use rusqlite::Row; -use sea_query::Iden; +use sea_query::{enum_def, IntoIden, IntoTableRef, SimpleExpr}; use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value; use std::collections::BTreeMap; @@ -8,6 +14,17 @@ use std::fmt::Display; use std::str::FromStr; use ts_rs::TS; +#[macro_export] +macro_rules! impl_model { + ($t:ty, $variant:ident) => { + impl $crate::Model for $t { + fn into_any(self) -> $crate::AnyModel { + $crate::AnyModel::$variant(self) + } + } + }; +} + #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "camelCase", tag = "type")] #[ts(export, export_to = "gen_models.ts")] @@ -39,9 +56,9 @@ pub enum EditorKeymap { } impl FromStr for EditorKeymap { - type Err = (); + type Err = crate::error::Error; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { match s { "default" => Ok(Self::Default), "vscode" => Ok(Self::Vscode), @@ -73,6 +90,7 @@ impl Default for EditorKeymap { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "settings")] pub struct Settings { #[ts(type = "\"settings\"")] pub model: String, @@ -94,52 +112,87 @@ pub struct Settings { pub editor_keymap: EditorKeymap, } -#[derive(Iden)] -pub enum SettingsIden { - #[iden = "settings"] - Table, - Model, - Id, - CreatedAt, - UpdatedAt, - - Appearance, - EditorFontSize, - EditorKeymap, - EditorSoftWrap, - InterfaceFontSize, - InterfaceScale, - OpenWorkspaceNewWindow, - Proxy, - Theme, - ThemeDark, - ThemeLight, - UpdateChannel, -} - -impl<'s> TryFrom<&Row<'s>> for Settings { - type Error = rusqlite::Error; +impl UpsertModelInfo for Settings { + fn table_name() -> impl IntoTableRef { + SettingsIden::Table + } + + fn id_column() -> impl IntoIden + Eq + Clone { + SettingsIden::Id + } + + fn get_id(&self) -> String { + self.id.clone() + } + + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use SettingsIden::*; + let proxy = match self.proxy { + None => None, + Some(p) => Some(serde_json::to_string(&p)?), + }; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (Appearance, self.appearance.as_str().into()), + (EditorFontSize, self.editor_font_size.into()), + (EditorKeymap, self.editor_keymap.to_string().into()), + (EditorSoftWrap, self.editor_soft_wrap.into()), + (InterfaceFontSize, self.interface_font_size.into()), + (InterfaceScale, self.interface_scale.into()), + (OpenWorkspaceNewWindow, self.open_workspace_new_window.into()), + (Theme, self.theme.as_str().into()), + (ThemeDark, self.theme_dark.as_str().into()), + (ThemeLight, self.theme_light.as_str().into()), + (UpdateChannel, self.update_channel.into()), + (Proxy, proxy.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + SettingsIden::UpdatedAt, + SettingsIden::Appearance, + SettingsIden::EditorFontSize, + SettingsIden::EditorKeymap, + SettingsIden::EditorSoftWrap, + SettingsIden::InterfaceFontSize, + SettingsIden::InterfaceScale, + SettingsIden::OpenWorkspaceNewWindow, + SettingsIden::Proxy, + SettingsIden::Theme, + SettingsIden::ThemeDark, + SettingsIden::ThemeLight, + SettingsIden::UpdateChannel, + ] + } - fn try_from(r: &Row<'s>) -> Result { - let proxy: Option = r.get("proxy")?; - let editor_keymap: String = r.get("editor_keymap")?; + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { + let proxy: Option = row.get("proxy")?; + let editor_keymap: String = row.get("editor_keymap")?; Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - appearance: r.get("appearance")?, - editor_font_size: r.get("editor_font_size")?, + id: row.get("id")?, + model: row.get("model")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + appearance: row.get("appearance")?, + editor_font_size: row.get("editor_font_size")?, editor_keymap: EditorKeymap::from_str(editor_keymap.as_str()).unwrap(), - editor_soft_wrap: r.get("editor_soft_wrap")?, - interface_font_size: r.get("interface_font_size")?, - interface_scale: r.get("interface_scale")?, - open_workspace_new_window: r.get("open_workspace_new_window")?, + editor_soft_wrap: row.get("editor_soft_wrap")?, + interface_font_size: row.get("interface_font_size")?, + interface_scale: row.get("interface_scale")?, + open_workspace_new_window: row.get("open_workspace_new_window")?, proxy: proxy.map(|p| -> ProxySetting { serde_json::from_str(p.as_str()).unwrap() }), - theme: r.get("theme")?, - theme_dark: r.get("theme_dark")?, - theme_light: r.get("theme_light")?, - update_channel: r.get("update_channel")?, + theme: row.get("theme")?, + theme_dark: row.get("theme_dark")?, + theme_light: row.get("theme_light")?, + update_channel: row.get("update_channel")?, }) } } @@ -147,6 +200,7 @@ impl<'s> TryFrom<&Row<'s>> for Settings { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "workspaces")] pub struct Workspace { #[ts(type = "\"workspace\"")] pub model: String, @@ -164,36 +218,61 @@ pub struct Workspace { pub setting_request_timeout: i32, } -#[derive(Iden)] -pub enum WorkspaceIden { - #[iden = "workspaces"] - Table, - Model, - Id, - CreatedAt, - UpdatedAt, +impl UpsertModelInfo for Workspace { + fn table_name() -> impl IntoTableRef { + WorkspaceIden::Table + } - Description, - Name, - SettingFollowRedirects, - SettingRequestTimeout, - SettingValidateCertificates, -} + fn id_column() -> impl IntoIden + Eq + Clone { + WorkspaceIden::Id + } -impl<'s> TryFrom<&Row<'s>> for Workspace { - type Error = rusqlite::Error; + fn get_id(&self) -> String { + self.id.clone() + } + + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use WorkspaceIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (Name, self.name.trim().into()), + (Description, self.description.into()), + (SettingFollowRedirects, self.setting_follow_redirects.into()), + (SettingRequestTimeout, self.setting_request_timeout.into()), + (SettingValidateCertificates, self.setting_validate_certificates.into()), + ]) + } - fn try_from(r: &Row<'s>) -> Result { + fn update_columns() -> Vec { + vec![ + WorkspaceIden::UpdatedAt, + WorkspaceIden::Name, + WorkspaceIden::Description, + WorkspaceIden::SettingRequestTimeout, + WorkspaceIden::SettingFollowRedirects, + WorkspaceIden::SettingRequestTimeout, + WorkspaceIden::SettingValidateCertificates, + ] + } + + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - name: r.get("name")?, - description: r.get("description")?, - setting_follow_redirects: r.get("setting_follow_redirects")?, - setting_request_timeout: r.get("setting_request_timeout")?, - setting_validate_certificates: r.get("setting_validate_certificates")?, + id: row.get("id")?, + model: row.get("model")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + name: row.get("name")?, + description: row.get("description")?, + setting_follow_redirects: row.get("setting_follow_redirects")?, + setting_request_timeout: row.get("setting_request_timeout")?, + setting_validate_certificates: row.get("setting_validate_certificates")?, }) } } @@ -213,6 +292,7 @@ impl Workspace { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "workspace_metas")] pub struct WorkspaceMeta { #[ts(type = "\"workspace_meta\"")] pub model: String, @@ -223,30 +303,50 @@ pub struct WorkspaceMeta { pub setting_sync_dir: Option, } -#[derive(Iden)] -pub enum WorkspaceMetaIden { - #[iden = "workspace_metas"] - Table, - Model, - Id, - WorkspaceId, - CreatedAt, - UpdatedAt, +impl UpsertModelInfo for WorkspaceMeta { + fn table_name() -> impl IntoTableRef { + WorkspaceMetaIden::Table + } - SettingSyncDir, -} + fn id_column() -> impl IntoIden + Eq + Clone { + WorkspaceMetaIden::Id + } -impl<'s> TryFrom<&Row<'s>> for WorkspaceMeta { - type Error = rusqlite::Error; + fn get_id(&self) -> String { + self.id.clone() + } - fn try_from(r: &Row<'s>) -> Result { + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use WorkspaceMetaIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (WorkspaceId, self.workspace_id.into()), + (SettingSyncDir, self.setting_sync_dir.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + WorkspaceMetaIden::UpdatedAt, + WorkspaceMetaIden::SettingSyncDir, + ] + } + + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { Ok(Self { - id: r.get("id")?, - workspace_id: r.get("workspace_id")?, - model: r.get("model")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - setting_sync_dir: r.get("setting_sync_dir")?, + id: row.get("id")?, + workspace_id: row.get("workspace_id")?, + model: row.get("model")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + setting_sync_dir: row.get("setting_sync_dir")?, }) } } @@ -279,6 +379,7 @@ pub struct Cookie { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "cookie_jars")] pub struct CookieJar { #[ts(type = "\"cookie_jar\"")] pub model: String, @@ -291,32 +392,53 @@ pub struct CookieJar { pub name: String, } -#[derive(Iden)] -pub enum CookieJarIden { - #[iden = "cookie_jars"] - Table, - Id, - Model, - WorkspaceId, - CreatedAt, - UpdatedAt, +impl UpsertModelInfo for CookieJar { + fn table_name() -> impl IntoTableRef { + CookieJarIden::Table + } - Cookies, - Name, -} + fn id_column() -> impl IntoIden + Eq + Clone { + CookieJarIden::Id + } -impl<'s> TryFrom<&Row<'s>> for CookieJar { - type Error = rusqlite::Error; + fn get_id(&self) -> String { + self.id.clone() + } - fn try_from(r: &Row<'s>) -> Result { - let cookies: String = r.get("cookies")?; + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use CookieJarIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (WorkspaceId, self.workspace_id.into()), + (Name, self.name.trim().into()), + (Cookies, serde_json::to_string(&self.cookies)?.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + CookieJarIden::UpdatedAt, + CookieJarIden::Name, + CookieJarIden::Cookies, + ] + } + + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { + let cookies: String = row.get("cookies")?; Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - workspace_id: r.get("workspace_id")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - name: r.get("name")?, + id: row.get("id")?, + model: row.get("model")?, + workspace_id: row.get("workspace_id")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + name: row.get("name")?, cookies: serde_json::from_str(cookies.as_str()).unwrap_or_default(), }) } @@ -325,6 +447,7 @@ impl<'s> TryFrom<&Row<'s>> for CookieJar { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "environments")] pub struct Environment { #[ts(type = "\"environment\"")] pub model: String, @@ -338,34 +461,55 @@ pub struct Environment { pub variables: Vec, } -#[derive(Iden)] -pub enum EnvironmentIden { - #[iden = "environments"] - Table, - Model, - Id, - CreatedAt, - UpdatedAt, - EnvironmentId, - WorkspaceId, +impl UpsertModelInfo for Environment { + fn table_name() -> impl IntoTableRef { + EnvironmentIden::Table + } - Name, - Variables, -} + fn id_column() -> impl IntoIden + Eq + Clone { + EnvironmentIden::Id + } -impl<'s> TryFrom<&Row<'s>> for Environment { - type Error = rusqlite::Error; + fn get_id(&self) -> String { + self.id.clone() + } + + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use EnvironmentIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (EnvironmentId, self.environment_id.into()), + (WorkspaceId, self.workspace_id.into()), + (Name, self.name.trim().into()), + (Variables, serde_json::to_string(&self.variables)?.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + EnvironmentIden::UpdatedAt, + EnvironmentIden::Name, + EnvironmentIden::Variables, + ] + } - fn try_from(r: &Row<'s>) -> Result { - let variables: String = r.get("variables")?; + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { + let variables: String = row.get("variables")?; Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - workspace_id: r.get("workspace_id")?, - environment_id: r.get("environment_id")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - name: r.get("name")?, + id: row.get("id")?, + model: row.get("model")?, + workspace_id: row.get("workspace_id")?, + environment_id: row.get("environment_id")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + name: row.get("name")?, variables: serde_json::from_str(variables.as_str()).unwrap_or_default(), }) } @@ -387,6 +531,7 @@ pub struct EnvironmentVariable { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "folders")] pub struct Folder { #[ts(type = "\"folder\"")] pub model: String, @@ -401,36 +546,59 @@ pub struct Folder { pub sort_priority: f32, } -#[derive(Iden)] -pub enum FolderIden { - #[iden = "folders"] - Table, - Id, - Model, - WorkspaceId, - FolderId, - CreatedAt, - UpdatedAt, +impl UpsertModelInfo for Folder { + fn table_name() -> impl IntoTableRef { + FolderIden::Table + } - Name, - Description, - SortPriority, -} + fn id_column() -> impl IntoIden + Eq + Clone { + FolderIden::Id + } -impl<'s> TryFrom<&Row<'s>> for Folder { - type Error = rusqlite::Error; + fn get_id(&self) -> String { + generate_model_id(ModelType::TypeFolder) + } + + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use FolderIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (WorkspaceId, self.workspace_id.into()), + (FolderId, self.folder_id.into()), + (Name, self.name.trim().into()), + (Description, self.description.into()), + (SortPriority, self.sort_priority.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + FolderIden::UpdatedAt, + FolderIden::Name, + FolderIden::Description, + FolderIden::FolderId, + FolderIden::SortPriority, + ] + } - fn try_from(r: &Row<'s>) -> Result { + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - sort_priority: r.get("sort_priority")?, - workspace_id: r.get("workspace_id")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - folder_id: r.get("folder_id")?, - name: r.get("name")?, - description: r.get("description")?, + id: row.get("id")?, + model: row.get("model")?, + sort_priority: row.get("sort_priority")?, + workspace_id: row.get("workspace_id")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + folder_id: row.get("folder_id")?, + name: row.get("name")?, + description: row.get("description")?, }) } } @@ -464,6 +632,7 @@ pub struct HttpUrlParameter { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "http_requests")] pub struct HttpRequest { #[ts(type = "\"http_request\"")] pub model: String, @@ -489,34 +658,62 @@ pub struct HttpRequest { pub url_parameters: Vec, } -#[derive(Iden)] -pub enum HttpRequestIden { - #[iden = "http_requests"] - Table, - Id, - Model, - CreatedAt, - UpdatedAt, - WorkspaceId, - FolderId, - - Authentication, - AuthenticationType, - Body, - BodyType, - Description, - Headers, - Method, - Name, - SortPriority, - Url, - UrlParameters, -} - -impl<'s> TryFrom<&Row<'s>> for HttpRequest { - type Error = rusqlite::Error; +impl UpsertModelInfo for HttpRequest { + fn table_name() -> impl IntoTableRef { + HttpRequestIden::Table + } + + fn id_column() -> impl IntoIden + Eq + Clone { + HttpRequestIden::Id + } + + fn get_id(&self) -> String { + self.id.to_string() + } + + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (WorkspaceId, self.workspace_id.into()), + (FolderId, self.folder_id.into()), + (Name, self.name.trim().into()), + (Description, self.description.into()), + (Url, self.url.into()), + (UrlParameters, serde_json::to_string(&self.url_parameters)?.into()), + (Method, self.method.into()), + (Body, serde_json::to_string(&self.body)?.into()), + (BodyType, self.body_type.into()), + (Authentication, serde_json::to_string(&self.authentication)?.into()), + (AuthenticationType, self.authentication_type.into()), + (Headers, serde_json::to_string(&self.headers)?.into()), + (SortPriority, self.sort_priority.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + UpdatedAt, + WorkspaceId, + Name, + Description, + FolderId, + Method, + Headers, + Body, + BodyType, + Authentication, + AuthenticationType, + Url, + UrlParameters, + SortPriority, + ] + } - fn try_from(r: &Row<'s>) -> Result { + fn from_row(r: &Row) -> rusqlite::Result { let url_parameters: String = r.get("url_parameters")?; let body: String = r.get("body")?; let authentication: String = r.get("authentication")?; @@ -562,6 +759,7 @@ impl Default for WebsocketConnectionState { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "websocket_connections")] pub struct WebsocketConnection { #[ts(type = "\"websocket_connection\"")] pub model: String, @@ -579,44 +777,69 @@ pub struct WebsocketConnection { pub url: String, } -#[derive(Iden)] -pub enum WebsocketConnectionIden { - #[iden = "websocket_connections"] - Table, - Id, - Model, - CreatedAt, - UpdatedAt, - WorkspaceId, - RequestId, +impl UpsertModelInfo for WebsocketConnection { + fn table_name() -> impl IntoTableRef { + WebsocketConnectionIden::Table + } - Elapsed, - Error, - Headers, - State, - Status, - Url, -} + fn id_column() -> impl IntoIden + Eq + Clone { + WebsocketConnectionIden::Id + } -impl<'s> TryFrom<&Row<'s>> for WebsocketConnection { - type Error = rusqlite::Error; + fn get_id(&self) -> String { + self.id.clone() + } - fn try_from(r: &Row<'s>) -> Result { - let headers: String = r.get("headers")?; - let state: String = r.get("state")?; + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use WebsocketConnectionIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (WorkspaceId, self.workspace_id.into()), + (RequestId, self.request_id.into()), + (Elapsed, self.elapsed.into()), + (Error, self.error.into()), + (Headers, serde_json::to_string(&self.headers)?.into()), + (State, serde_json::to_value(&self.state)?.as_str().into()), + (Status, self.status.into()), + (Url, self.url.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + WebsocketConnectionIden::UpdatedAt, + WebsocketConnectionIden::Elapsed, + WebsocketConnectionIden::Error, + WebsocketConnectionIden::Headers, + WebsocketConnectionIden::State, + WebsocketConnectionIden::Status, + WebsocketConnectionIden::Url, + ] + } + + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { + let headers: String = row.get("headers")?; + let state: String = row.get("state")?; Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - workspace_id: r.get("workspace_id")?, - request_id: r.get("request_id")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - url: r.get("url")?, + id: row.get("id")?, + model: row.get("model")?, + workspace_id: row.get("workspace_id")?, + request_id: row.get("request_id")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + url: row.get("url")?, headers: serde_json::from_str(headers.as_str()).unwrap_or_default(), - elapsed: r.get("elapsed")?, - error: r.get("error")?, + elapsed: row.get("elapsed")?, + error: row.get("error")?, state: serde_json::from_str(format!(r#""{state}""#).as_str()).unwrap(), - status: r.get("status")?, + status: row.get("status")?, }) } } @@ -638,6 +861,7 @@ impl Default for WebsocketMessageType { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "websocket_requests")] pub struct WebsocketRequest { #[ts(type = "\"websocket_request\"")] pub model: String, @@ -659,51 +883,81 @@ pub struct WebsocketRequest { pub url_parameters: Vec, } -#[derive(Iden)] -pub enum WebsocketRequestIden { - #[iden = "websocket_requests"] - Table, - Id, - Model, - CreatedAt, - UpdatedAt, - WorkspaceId, - FolderId, - - Authentication, - AuthenticationType, - Message, - Description, - Headers, - Name, - SortPriority, - Url, - UrlParameters, -} - -impl<'s> TryFrom<&Row<'s>> for WebsocketRequest { - type Error = rusqlite::Error; +impl UpsertModelInfo for WebsocketRequest { + fn table_name() -> impl IntoTableRef { + WebsocketRequestIden::Table + } - fn try_from(r: &Row<'s>) -> Result { - let url_parameters: String = r.get("url_parameters")?; - let authentication: String = r.get("authentication")?; - let headers: String = r.get("headers")?; + fn id_column() -> impl IntoIden + Eq + Clone { + WebsocketRequestIden::Id + } + + fn get_id(&self) -> String { + self.id.clone() + } + + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use WebsocketRequestIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (WorkspaceId, self.workspace_id.into()), + (FolderId, self.folder_id.as_ref().map(|s| s.as_str()).into()), + (Authentication, serde_json::to_string(&self.authentication)?.into()), + (AuthenticationType, self.authentication_type.as_ref().map(|s| s.as_str()).into()), + (Description, self.description.into()), + (Headers, serde_json::to_string(&self.headers)?.into()), + (Message, self.message.into()), + (Name, self.name.trim().into()), + (SortPriority, self.sort_priority.into()), + (Url, self.url.into()), + (UrlParameters, serde_json::to_string(&self.url_parameters)?.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + WebsocketRequestIden::UpdatedAt, + WebsocketRequestIden::WorkspaceId, + WebsocketRequestIden::FolderId, + WebsocketRequestIden::Authentication, + WebsocketRequestIden::AuthenticationType, + WebsocketRequestIden::Description, + WebsocketRequestIden::Headers, + WebsocketRequestIden::Message, + WebsocketRequestIden::Name, + WebsocketRequestIden::SortPriority, + WebsocketRequestIden::Url, + WebsocketRequestIden::UrlParameters, + ] + } + + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { + let url_parameters: String = row.get("url_parameters")?; + let authentication: String = row.get("authentication")?; + let headers: String = row.get("headers")?; Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - sort_priority: r.get("sort_priority")?, - workspace_id: r.get("workspace_id")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - url: r.get("url")?, + id: row.get("id")?, + model: row.get("model")?, + sort_priority: row.get("sort_priority")?, + workspace_id: row.get("workspace_id")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + url: row.get("url")?, url_parameters: serde_json::from_str(url_parameters.as_str()).unwrap_or_default(), - message: r.get("message")?, - description: r.get("description")?, + message: row.get("message")?, + description: row.get("description")?, authentication: serde_json::from_str(authentication.as_str()).unwrap_or_default(), - authentication_type: r.get("authentication_type")?, + authentication_type: row.get("authentication_type")?, headers: serde_json::from_str(headers.as_str()).unwrap_or_default(), - folder_id: r.get("folder_id")?, - name: r.get("name")?, + folder_id: row.get("folder_id")?, + name: row.get("name")?, }) } } @@ -730,6 +984,7 @@ impl Default for WebsocketEventType { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "websocket_events")] pub struct WebsocketEvent { #[ts(type = "\"websocket_event\"")] pub model: String, @@ -745,38 +1000,60 @@ pub struct WebsocketEvent { pub message_type: WebsocketEventType, } -#[derive(Iden)] -pub enum WebsocketEventIden { - #[iden = "websocket_events"] - Table, - Model, - Id, - CreatedAt, - UpdatedAt, - WorkspaceId, - RequestId, - ConnectionId, - IsServer, +impl UpsertModelInfo for WebsocketEvent { + fn table_name() -> impl IntoTableRef { + WebsocketEventIden::Table + } - MessageType, - Message, -} + fn id_column() -> impl IntoIden + Eq + Clone { + WebsocketEventIden::Id + } -impl<'s> TryFrom<&Row<'s>> for WebsocketEvent { - type Error = rusqlite::Error; + fn get_id(&self) -> String { + self.id.clone() + } - fn try_from(r: &Row<'s>) -> Result { - let message_type: String = r.get("message_type")?; + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use WebsocketEventIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (WorkspaceId, self.workspace_id.into()), + (ConnectionId, self.connection_id.into()), + (RequestId, self.request_id.into()), + (MessageType, serde_json::to_string(&self.message_type)?.into()), + (IsServer, self.is_server.into()), + (Message, self.message.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + WebsocketEventIden::UpdatedAt, + WebsocketEventIden::MessageType, + WebsocketEventIden::IsServer, + WebsocketEventIden::Message, + ] + } + + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { + let message_type: String = row.get("message_type")?; Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - workspace_id: r.get("workspace_id")?, - request_id: r.get("request_id")?, - connection_id: r.get("connection_id")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - message: r.get("message")?, - is_server: r.get("is_server")?, + id: row.get("id")?, + model: row.get("model")?, + workspace_id: row.get("workspace_id")?, + request_id: row.get("request_id")?, + connection_id: row.get("connection_id")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + message: row.get("message")?, + is_server: row.get("is_server")?, message_type: serde_json::from_str(message_type.as_str()).unwrap_or_default(), }) } @@ -808,6 +1085,7 @@ impl Default for HttpResponseState { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "http_responses")] pub struct HttpResponse { #[ts(type = "\"http_response\"")] pub model: String, @@ -831,35 +1109,66 @@ pub struct HttpResponse { pub version: Option, } -#[derive(Iden)] -pub enum HttpResponseIden { - #[iden = "http_responses"] - Table, - Model, - Id, - CreatedAt, - UpdatedAt, - WorkspaceId, - RequestId, - - BodyPath, - ContentLength, - Elapsed, - ElapsedHeaders, - Error, - Headers, - RemoteAddr, - Status, - StatusReason, - State, - Url, - Version, -} +impl UpsertModelInfo for HttpResponse { + fn table_name() -> impl IntoTableRef { + HttpResponseIden::Table + } -impl<'s> TryFrom<&Row<'s>> for HttpResponse { - type Error = rusqlite::Error; + fn id_column() -> impl IntoIden + Eq + Clone { + HttpResponseIden::Id + } + + fn get_id(&self) -> String { + self.id.clone() + } - fn try_from(r: &Row<'s>) -> Result { + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use HttpResponseIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (RequestId, self.request_id.into()), + (WorkspaceId, self.workspace_id.into()), + (BodyPath, self.body_path.into()), + (ContentLength, self.content_length.into()), + (Elapsed, self.elapsed.into()), + (ElapsedHeaders, self.elapsed_headers.into()), + (Error, self.error.into()), + (Headers, serde_json::to_string(&self.headers)?.into()), + (RemoteAddr, self.remote_addr.into()), + (State, serde_json::to_value(self.state)?.as_str().into()), + (Status, self.status.into()), + (StatusReason, self.status_reason.into()), + (Url, self.url.into()), + (Version, self.version.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + HttpResponseIden::UpdatedAt, + HttpResponseIden::BodyPath, + HttpResponseIden::ContentLength, + HttpResponseIden::Elapsed, + HttpResponseIden::ElapsedHeaders, + HttpResponseIden::Error, + HttpResponseIden::Headers, + HttpResponseIden::RemoteAddr, + HttpResponseIden::State, + HttpResponseIden::Status, + HttpResponseIden::StatusReason, + HttpResponseIden::Url, + HttpResponseIden::Version, + ] + } + + fn from_row(r: &Row) -> rusqlite::Result + where + Self: Sized, + { let headers: String = r.get("headers")?; let state: String = r.get("state")?; Ok(Self { @@ -885,15 +1194,6 @@ impl<'s> TryFrom<&Row<'s>> for HttpResponse { } } -impl HttpResponse { - pub fn new() -> Self { - Self { - model: "http_response".to_string(), - ..Default::default() - } - } -} - #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] @@ -910,6 +1210,7 @@ pub struct GrpcMetadataEntry { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "grpc_requests")] pub struct GrpcRequest { #[ts(type = "\"grpc_request\"")] pub model: String, @@ -932,51 +1233,82 @@ pub struct GrpcRequest { pub url: String, } -#[derive(Iden)] -pub enum GrpcRequestIden { - #[iden = "grpc_requests"] - Table, - Id, - Model, - CreatedAt, - UpdatedAt, - WorkspaceId, - FolderId, - - Authentication, - AuthenticationType, - Description, - Message, - Metadata, - Method, - Name, - Service, - SortPriority, - Url, -} - -impl<'s> TryFrom<&Row<'s>> for GrpcRequest { - type Error = rusqlite::Error; +impl UpsertModelInfo for GrpcRequest { + fn table_name() -> impl IntoTableRef { + GrpcRequestIden::Table + } - fn try_from(r: &Row<'s>) -> Result { - let authentication: String = r.get("authentication")?; - let metadata: String = r.get("metadata")?; + fn id_column() -> impl IntoIden + Eq + Clone { + GrpcRequestIden::Id + } + + fn get_id(&self) -> String { + self.id.clone() + } + + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use GrpcRequestIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (Name, self.name.trim().into()), + (Description, self.description.into()), + (WorkspaceId, self.workspace_id.into()), + (FolderId, self.folder_id.into()), + (SortPriority, self.sort_priority.into()), + (Url, self.url.into()), + (Service, self.service.into()), + (Method, self.method.into()), + (Message, self.message.into()), + (AuthenticationType, self.authentication_type.into()), + (Authentication, serde_json::to_string(&self.authentication)?.into()), + (Metadata, serde_json::to_string(&self.metadata)?.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + GrpcRequestIden::UpdatedAt, + GrpcRequestIden::WorkspaceId, + GrpcRequestIden::Name, + GrpcRequestIden::Description, + GrpcRequestIden::FolderId, + GrpcRequestIden::SortPriority, + GrpcRequestIden::Url, + GrpcRequestIden::Service, + GrpcRequestIden::Method, + GrpcRequestIden::Message, + GrpcRequestIden::AuthenticationType, + GrpcRequestIden::Authentication, + GrpcRequestIden::Metadata, + ] + } + + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { + let authentication: String = row.get("authentication")?; + let metadata: String = row.get("metadata")?; Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - workspace_id: r.get("workspace_id")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - folder_id: r.get("folder_id")?, - name: r.get("name")?, - description: r.get("description")?, - service: r.get("service")?, - method: r.get("method")?, - message: r.get("message")?, - authentication_type: r.get("authentication_type")?, + id: row.get("id")?, + model: row.get("model")?, + workspace_id: row.get("workspace_id")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + folder_id: row.get("folder_id")?, + name: row.get("name")?, + description: row.get("description")?, + service: row.get("service")?, + method: row.get("method")?, + message: row.get("message")?, + authentication_type: row.get("authentication_type")?, authentication: serde_json::from_str(authentication.as_str()).unwrap_or_default(), - url: r.get("url")?, - sort_priority: r.get("sort_priority")?, + url: row.get("url")?, + sort_priority: row.get("sort_priority")?, metadata: serde_json::from_str(metadata.as_str()).unwrap_or_default(), }) } @@ -1000,6 +1332,7 @@ impl Default for GrpcConnectionState { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "grpc_connections")] pub struct GrpcConnection { #[ts(type = "\"grpc_connection\"")] pub model: String, @@ -1019,47 +1352,74 @@ pub struct GrpcConnection { pub url: String, } -#[derive(Iden)] -pub enum GrpcConnectionIden { - #[iden = "grpc_connections"] - Table, - Model, - Id, - CreatedAt, - UpdatedAt, - WorkspaceId, - RequestId, +impl UpsertModelInfo for GrpcConnection { + fn table_name() -> impl IntoTableRef { + GrpcConnectionIden::Table + } - Elapsed, - Error, - Method, - Service, - State, - Status, - Trailers, - Url, -} + fn id_column() -> impl IntoIden + Eq + Clone { + GrpcConnectionIden::Id + } -impl<'s> TryFrom<&Row<'s>> for GrpcConnection { - type Error = rusqlite::Error; + fn get_id(&self) -> String { + self.id.clone() + } - fn try_from(r: &Row<'s>) -> Result { - let trailers: String = r.get("trailers")?; - let state: String = r.get("state")?; + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use GrpcConnectionIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (WorkspaceId, self.workspace_id.into()), + (RequestId, self.request_id.into()), + (Service, self.service.into()), + (Method, self.method.into()), + (Elapsed, self.elapsed.into()), + (State, serde_json::to_value(&self.state)?.as_str().into()), + (Status, self.status.into()), + (Error, self.error.as_ref().map(|s| s.as_str()).into()), + (Trailers, serde_json::to_string(&self.trailers)?.into()), + (Url, self.url.into()), + ]) + } + + fn update_columns() -> Vec { + vec![ + GrpcConnectionIden::UpdatedAt, + GrpcConnectionIden::Service, + GrpcConnectionIden::Method, + GrpcConnectionIden::Elapsed, + GrpcConnectionIden::Status, + GrpcConnectionIden::State, + GrpcConnectionIden::Error, + GrpcConnectionIden::Trailers, + GrpcConnectionIden::Url, + ] + } + + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { + let trailers: String = row.get("trailers")?; + let state: String = row.get("state")?; Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - workspace_id: r.get("workspace_id")?, - request_id: r.get("request_id")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - service: r.get("service")?, - method: r.get("method")?, - elapsed: r.get("elapsed")?, + id: row.get("id")?, + model: row.get("model")?, + workspace_id: row.get("workspace_id")?, + request_id: row.get("request_id")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + service: row.get("service")?, + method: row.get("method")?, + elapsed: row.get("elapsed")?, state: serde_json::from_str(format!(r#""{state}""#).as_str()).unwrap(), - status: r.get("status")?, - url: r.get("url")?, - error: r.get("error")?, + status: row.get("status")?, + url: row.get("url")?, + error: row.get("error")?, trailers: serde_json::from_str(trailers.as_str()).unwrap_or_default(), }) } @@ -1086,6 +1446,7 @@ impl Default for GrpcEventType { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "grpc_events")] pub struct GrpcEvent { #[ts(type = "\"grpc_event\"")] pub model: String, @@ -1103,44 +1464,68 @@ pub struct GrpcEvent { pub status: Option, } -#[derive(Iden)] -pub enum GrpcEventIden { - #[iden = "grpc_events"] - Table, - Model, - Id, - CreatedAt, - UpdatedAt, - WorkspaceId, - RequestId, - ConnectionId, +impl UpsertModelInfo for GrpcEvent { + fn table_name() -> impl IntoTableRef { + GrpcEventIden::Table + } - Content, - Error, - EventType, - Metadata, - Status, -} + fn id_column() -> impl IntoIden + Eq + Clone { + GrpcEventIden::Id + } -impl<'s> TryFrom<&Row<'s>> for GrpcEvent { - type Error = rusqlite::Error; + fn get_id(&self) -> String { + self.id.clone() + } + + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use GrpcEventIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (WorkspaceId, self.workspace_id.into()), + (RequestId, self.request_id.into()), + (ConnectionId, self.connection_id.into()), + (Content, self.content.into()), + (EventType, serde_json::to_string(&self.event_type)?.into()), + (Metadata, serde_json::to_string(&self.metadata)?.into()), + (Status, self.status.into()), + (Error, self.error.into()), + ]) + } - fn try_from(r: &Row<'s>) -> Result { - let event_type: String = r.get("event_type")?; - let metadata: String = r.get("metadata")?; + fn update_columns() -> Vec { + vec![ + GrpcEventIden::UpdatedAt, + GrpcEventIden::Content, + GrpcEventIden::EventType, + GrpcEventIden::Metadata, + GrpcEventIden::Status, + GrpcEventIden::Error, + ] + } + + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { + let event_type: String = row.get("event_type")?; + let metadata: String = row.get("metadata")?; Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - workspace_id: r.get("workspace_id")?, - request_id: r.get("request_id")?, - connection_id: r.get("connection_id")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - content: r.get("content")?, + id: row.get("id")?, + model: row.get("model")?, + workspace_id: row.get("workspace_id")?, + request_id: row.get("request_id")?, + connection_id: row.get("connection_id")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + content: row.get("content")?, event_type: serde_json::from_str(event_type.as_str()).unwrap_or_default(), metadata: serde_json::from_str(metadata.as_str()).unwrap_or_default(), - status: r.get("status")?, - error: r.get("error")?, + status: row.get("status")?, + error: row.get("error")?, }) } } @@ -1148,6 +1533,7 @@ impl<'s> TryFrom<&Row<'s>> for GrpcEvent { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "plugins")] pub struct Plugin { #[ts(type = "\"plugin\"")] pub model: String, @@ -1161,34 +1547,57 @@ pub struct Plugin { pub url: Option, } -#[derive(Iden)] -pub enum PluginIden { - #[iden = "plugins"] - Table, - Model, - Id, - CreatedAt, - UpdatedAt, +impl UpsertModelInfo for Plugin { + fn table_name() -> impl IntoTableRef { + PluginIden::Table + } - CheckedAt, - Directory, - Enabled, - Url, -} + fn id_column() -> impl IntoIden + Eq + Clone { + PluginIden::Id + } -impl<'s> TryFrom<&Row<'s>> for Plugin { - type Error = rusqlite::Error; + fn get_id(&self) -> String { + self.id.clone() + } + + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use PluginIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (CheckedAt, self.checked_at.into()), + (Directory, self.directory.into()), + (Url, self.url.into()), + (Enabled, self.enabled.into()), + ]) + } - fn try_from(r: &Row<'s>) -> Result { + fn update_columns() -> Vec { + vec![ + PluginIden::UpdatedAt, + PluginIden::CheckedAt, + PluginIden::Directory, + PluginIden::Url, + PluginIden::Enabled, + ] + } + + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - checked_at: r.get("checked_at")?, - url: r.get("url")?, - directory: r.get("directory")?, - enabled: r.get("enabled")?, + id: row.get("id")?, + model: row.get("model")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + checked_at: row.get("checked_at")?, + url: row.get("url")?, + directory: row.get("directory")?, + enabled: row.get("enabled")?, }) } } @@ -1196,6 +1605,7 @@ impl<'s> TryFrom<&Row<'s>> for Plugin { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "sync_states")] pub struct SyncState { #[ts(type = "\"sync_state\"")] pub model: String, @@ -1211,54 +1621,61 @@ pub struct SyncState { pub sync_dir: String, } -#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] -#[serde(default, rename_all = "camelCase")] -#[ts(export, export_to = "gen_models.ts")] -pub struct SyncHistory { - #[ts(type = "\"sync_history\"")] - pub model: String, - pub id: String, - pub workspace_id: String, - pub created_at: NaiveDateTime, +impl UpsertModelInfo for SyncState { + fn table_name() -> impl IntoTableRef { + SyncStateIden::Table + } - pub states: Vec, - pub checksum: String, - pub rel_path: String, - pub sync_dir: String, -} + fn id_column() -> impl IntoIden + Eq + Clone { + SyncStateIden::Id + } -#[derive(Iden)] -pub enum SyncStateIden { - #[iden = "sync_states"] - Table, - Model, - Id, - WorkspaceId, - CreatedAt, - UpdatedAt, + fn get_id(&self) -> String { + self.id.clone() + } - Checksum, - FlushedAt, - ModelId, - RelPath, - SyncDir, -} + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>> { + use SyncStateIden::*; + Ok(vec![ + (CreatedAt, upsert_date(source, self.created_at)), + (UpdatedAt, upsert_date(source, self.updated_at)), + (WorkspaceId, self.workspace_id.into()), + (FlushedAt, self.flushed_at.into()), + (Checksum, self.checksum.into()), + (ModelId, self.model_id.into()), + (RelPath, self.rel_path.into()), + (SyncDir, self.sync_dir.into()), + ]) + } -impl<'s> TryFrom<&Row<'s>> for SyncState { - type Error = rusqlite::Error; + fn update_columns() -> Vec { + vec![ + SyncStateIden::UpdatedAt, + SyncStateIden::FlushedAt, + SyncStateIden::Checksum, + SyncStateIden::RelPath, + SyncStateIden::SyncDir, + ] + } - fn try_from(r: &Row<'s>) -> Result { + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized, + { Ok(Self { - id: r.get("id")?, - workspace_id: r.get("workspace_id")?, - model: r.get("model")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, - flushed_at: r.get("flushed_at")?, - checksum: r.get("checksum")?, - model_id: r.get("model_id")?, - sync_dir: r.get("sync_dir")?, - rel_path: r.get("rel_path")?, + id: row.get("id")?, + workspace_id: row.get("workspace_id")?, + model: row.get("model")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, + flushed_at: row.get("flushed_at")?, + checksum: row.get("checksum")?, + model_id: row.get("model_id")?, + sync_dir: row.get("sync_dir")?, + rel_path: row.get("rel_path")?, }) } } @@ -1266,6 +1683,7 @@ impl<'s> TryFrom<&Row<'s>> for SyncState { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "key_values")] pub struct KeyValue { #[ts(type = "\"key_value\"")] pub model: String, @@ -1277,23 +1695,10 @@ pub struct KeyValue { pub value: String, } -#[derive(Iden)] -pub enum KeyValueIden { - #[iden = "key_values"] - Table, - Model, - CreatedAt, - UpdatedAt, - - Key, - Namespace, - Value, -} - impl<'s> TryFrom<&Row<'s>> for KeyValue { type Error = rusqlite::Error; - fn try_from(r: &Row<'s>) -> Result { + fn try_from(r: &Row<'s>) -> std::result::Result { Ok(Self { model: r.get("model")?, created_at: r.get("created_at")?, @@ -1308,6 +1713,7 @@ impl<'s> TryFrom<&Row<'s>> for KeyValue { #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] +#[enum_def(table_name = "plugin_key_values")] pub struct PluginKeyValue { #[ts(type = "\"plugin_key_value\"")] pub model: String, @@ -1319,23 +1725,10 @@ pub struct PluginKeyValue { pub value: String, } -#[derive(Iden)] -pub enum PluginKeyValueIden { - #[iden = "plugin_key_values"] - Table, - Model, - CreatedAt, - UpdatedAt, - - PluginName, - Key, - Value, -} - impl<'s> TryFrom<&Row<'s>> for PluginKeyValue { type Error = rusqlite::Error; - fn try_from(r: &Row<'s>) -> Result { + fn try_from(r: &Row<'s>) -> std::result::Result { Ok(Self { model: r.get("model")?, created_at: r.get("created_at")?, @@ -1396,30 +1789,62 @@ impl ModelType { } } -#[derive(Debug, Clone, Serialize, TS)] -#[serde(rename_all = "camelCase", untagged)] -#[ts(export, export_to = "gen_models.ts")] -pub enum AnyModel { - CookieJar(CookieJar), - Environment(Environment), - Folder(Folder), - GrpcConnection(GrpcConnection), - GrpcEvent(GrpcEvent), - GrpcRequest(GrpcRequest), - HttpRequest(HttpRequest), - HttpResponse(HttpResponse), - Plugin(Plugin), - Settings(Settings), - KeyValue(KeyValue), - Workspace(Workspace), - WorkspaceMeta(WorkspaceMeta), - WebsocketConnection(WebsocketConnection), - WebsocketEvent(WebsocketEvent), - WebsocketRequest(WebsocketRequest), +#[macro_export] +macro_rules! define_any_model { + ($($type:ident),* $(,)?) => { + #[derive(Debug, Clone, Serialize, TS)] + #[serde(rename_all = "camelCase", untagged)] + #[ts(export, export_to = "gen_models.ts")] + pub enum AnyModel { + $( + $type($type), + )* + } + + $( + impl From<$type> for AnyModel { + fn from(value: $type) -> Self { + AnyModel::$type(value) + } + } + + impl From for $type { + fn from(value: AnyModel) -> $type { + match value { + AnyModel::$type(inner) => inner, + _ => panic!( // Should never happen because this macro also generates the enum variant + "Tried to convert AnyModel into `{}`, but found a different variant", + stringify!($type) + ), + } + } + } + )* + }; +} + +define_any_model! { + CookieJar, + Environment, + Folder, + GrpcConnection, + GrpcEvent, + GrpcRequest, + HttpRequest, + HttpResponse, + KeyValue, + Plugin, + Settings, + SyncState, + WebsocketConnection, + WebsocketEvent, + WebsocketRequest, + Workspace, + WorkspaceMeta, } impl<'de> Deserialize<'de> for AnyModel { - fn deserialize(deserializer: D) -> Result + fn deserialize(deserializer: D) -> std::result::Result where D: Deserializer<'de>, { @@ -1464,3 +1889,62 @@ impl<'de> Deserialize<'de> for AnyModel { Ok(model) } } + +impl AnyModel { + pub fn resolved_name(&self) -> String { + let compute_name = |name: &str, url: &str, fallback: &str| -> String { + if !name.is_empty() { + return name.to_string(); + } + let without_variables = url.replace(r"\$\{\[\s*([^\]\s]+)\s*]}", "$1"); + if without_variables.is_empty() { + fallback.to_string() + } else { + without_variables + } + }; + + match self.clone() { + AnyModel::CookieJar(v) => v.name, + AnyModel::Environment(v) => v.name, + AnyModel::Folder(v) => v.name, + AnyModel::GrpcRequest(v) => compute_name(&v.name, &v.url, "gRPC Request"), + AnyModel::HttpRequest(v) => compute_name(&v.name, &v.url, "HTTP Request"), + AnyModel::WebsocketRequest(v) => compute_name(&v.name, &v.url, "WebSocket Request"), + AnyModel::Workspace(v) => v.name, + _ => "No Name".to_string(), + } + } +} + +pub trait UpsertModelInfo { + fn table_name() -> impl IntoTableRef; + fn id_column() -> impl IntoIden + Eq + Clone; + fn get_id(&self) -> String; + fn insert_values( + self, + source: &UpdateSource, + ) -> Result)>>; + fn update_columns() -> Vec; + fn from_row(row: &Row) -> rusqlite::Result + where + Self: Sized; +} + +// Generate the created_at or updated_at timestamps for an upsert operation, depending on the ID +// provided. +fn upsert_date(update_source: &UpdateSource, dt: NaiveDateTime) -> SimpleExpr { + match update_source { + // Sync and import operations always preserve timestamps + UpdateSource::Sync | UpdateSource::Import => { + if dt.and_utc().timestamp() == 0 { + // Sometimes data won't have timestamps (partial data) + Utc::now().naive_utc().into() + } else { + dt.into() + } + } + // Other sources will always update to the latest time + _ => Utc::now().naive_utc().into(), + } +} diff --git a/src-tauri/yaak-models/src/plugin.rs b/src-tauri/yaak-models/src/plugin.rs deleted file mode 100644 index 8b875a0d5..000000000 --- a/src-tauri/yaak-models/src/plugin.rs +++ /dev/null @@ -1,81 +0,0 @@ -use log::info; -use r2d2::Pool; -use r2d2_sqlite::SqliteConnectionManager; -use serde::Deserialize; -use sqlx::migrate::Migrator; -use sqlx::sqlite::SqliteConnectOptions; -use sqlx::SqlitePool; -use std::fs::create_dir_all; -use std::path::PathBuf; -use std::str::FromStr; -use std::time::Duration; -use tauri::async_runtime::Mutex; -use tauri::path::BaseDirectory; -use tauri::plugin::TauriPlugin; -use tauri::{plugin, AppHandle, Manager, Runtime}; - -pub struct SqliteConnection(pub Mutex>); - -#[derive(Default, Deserialize)] -pub struct PluginConfig { - // Nothing yet (will be configurable in tauri.conf.json -} - -/// Tauri SQL plugin builder. -#[derive(Default)] -pub struct Builder { - // Nothing Yet -} - -impl Builder { - pub fn new() -> Self { - Self::default() - } - - pub fn build(&self) -> TauriPlugin> { - plugin::Builder::>::new("yaak_models") - .setup(|app, _api| { - let app_path = app.path().app_data_dir().unwrap(); - create_dir_all(app_path.clone()).expect("Problem creating App directory!"); - - let db_file_path = app_path.join("db.sqlite"); - - { - let db_file_path = db_file_path.clone(); - tauri::async_runtime::block_on(async move { - must_migrate_db(app.app_handle(), &db_file_path).await; - }); - }; - - let manager = SqliteConnectionManager::file(db_file_path); - let pool = Pool::builder() - .max_size(100) // Up from 10 (just in case) - .connection_timeout(Duration::from_secs(10)) // Down from 30 - .build(manager) - .unwrap(); - - app.manage(SqliteConnection(Mutex::new(pool))); - - Ok(()) - }) - .build() - } -} - -async fn must_migrate_db(app_handle: &AppHandle, sqlite_file_path: &PathBuf) { - info!("Connecting to database at {sqlite_file_path:?}"); - let sqlite_file_path = sqlite_file_path.to_str().unwrap().to_string(); - let opts = SqliteConnectOptions::from_str(&sqlite_file_path).unwrap().create_if_missing(true); - let pool = SqlitePool::connect_with(opts).await.expect("Failed to connect to database"); - let p = app_handle - .path() - .resolve("migrations", BaseDirectory::Resource) - .expect("failed to resolve resource"); - - info!("Running database migrations from: {}", p.to_string_lossy()); - let mut m = Migrator::new(p).await.expect("Failed to load migrations"); - m.set_ignore_missing(true); // So we can roll back versions and not crash - m.run(&pool).await.expect("Failed to run migrations"); - - info!("Database migrations complete"); -} diff --git a/src-tauri/yaak-models/src/queries.rs b/src-tauri/yaak-models/src/queries.rs deleted file mode 100644 index 71210bbc2..000000000 --- a/src-tauri/yaak-models/src/queries.rs +++ /dev/null @@ -1,2761 +0,0 @@ -use crate::error::Error::ModelNotFound; -use crate::error::Result; -use crate::models::{ - AnyModel, CookieJar, CookieJarIden, Environment, EnvironmentIden, Folder, FolderIden, - GrpcConnection, GrpcConnectionIden, GrpcConnectionState, GrpcEvent, GrpcEventIden, GrpcRequest, - GrpcRequestIden, HttpRequest, HttpRequestIden, HttpResponse, HttpResponseHeader, - HttpResponseIden, HttpResponseState, KeyValue, KeyValueIden, ModelType, Plugin, PluginIden, - PluginKeyValue, PluginKeyValueIden, Settings, SettingsIden, SyncState, SyncStateIden, - WebsocketConnection, WebsocketConnectionIden, WebsocketConnectionState, WebsocketEvent, - WebsocketEventIden, WebsocketRequest, WebsocketRequestIden, Workspace, WorkspaceIden, - WorkspaceMeta, WorkspaceMetaIden, -}; -use crate::plugin::SqliteConnection; -use chrono::{NaiveDateTime, Utc}; -use log::{debug, error, info, warn}; -use nanoid::nanoid; -use rusqlite::OptionalExtension; -use sea_query::ColumnRef::Asterisk; -use sea_query::Keyword::CurrentTimestamp; -use sea_query::{Cond, Expr, OnConflict, Order, Query, SqliteQueryBuilder}; -use sea_query_rusqlite::RusqliteBinder; -use serde::{Deserialize, Serialize}; -use std::fs; -use std::path::Path; -use tauri::{AppHandle, Emitter, Listener, Manager, Runtime, WebviewWindow}; -use ts_rs::TS; - -const MAX_HISTORY_ITEMS: usize = 20; - -pub async fn set_key_value_string( - app_handle: &AppHandle, - namespace: &str, - key: &str, - value: &str, - update_source: &UpdateSource, -) -> (KeyValue, bool) { - let encoded = serde_json::to_string(value); - set_key_value_raw(app_handle, namespace, key, &encoded.unwrap(), update_source).await -} - -pub async fn set_key_value_int( - app_handle: &AppHandle, - namespace: &str, - key: &str, - value: i32, - update_source: &UpdateSource, -) -> (KeyValue, bool) { - let encoded = serde_json::to_string(&value); - set_key_value_raw(app_handle, namespace, key, &encoded.unwrap(), update_source).await -} - -pub async fn get_key_value_string( - app_handle: &AppHandle, - namespace: &str, - key: &str, - default: &str, -) -> String { - match get_key_value_raw(app_handle, namespace, key).await { - None => default.to_string(), - Some(v) => { - let result = serde_json::from_str(&v.value); - match result { - Ok(v) => v, - Err(e) => { - error!("Failed to parse string key value: {}", e); - default.to_string() - } - } - } - } -} - -pub async fn get_key_value_int( - app_handle: &AppHandle, - namespace: &str, - key: &str, - default: i32, -) -> i32 { - match get_key_value_raw(app_handle, namespace, key).await { - None => default.clone(), - Some(v) => { - let result = serde_json::from_str(&v.value); - match result { - Ok(v) => v, - Err(e) => { - error!("Failed to parse int key value: {}", e); - default.clone() - } - } - } - } -} - -pub async fn set_key_value_raw( - app_handle: &AppHandle, - namespace: &str, - key: &str, - value: &str, - update_source: &UpdateSource, -) -> (KeyValue, bool) { - let existing = get_key_value_raw(app_handle, namespace, key).await; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::insert() - .into_table(KeyValueIden::Table) - .columns([ - KeyValueIden::CreatedAt, - KeyValueIden::UpdatedAt, - KeyValueIden::Namespace, - KeyValueIden::Key, - KeyValueIden::Value, - ]) - .values_panic([ - CurrentTimestamp.into(), - CurrentTimestamp.into(), - namespace.into(), - key.into(), - value.into(), - ]) - .on_conflict( - OnConflict::new() - .update_columns([KeyValueIden::UpdatedAt, KeyValueIden::Value]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str()).expect("Failed to prepare KeyValue upsert"); - let m: KeyValue = stmt - .query_row(&*params.as_params(), |row| row.try_into()) - .expect("Failed to upsert KeyValue"); - emit_upserted_model(app_handle, &AnyModel::KeyValue(m.to_owned()), update_source); - (m, existing.is_none()) -} - -pub async fn delete_key_value( - app_handle: &AppHandle, - namespace: &str, - key: &str, - update_source: &UpdateSource, -) { - let kv = match get_key_value_raw(app_handle, namespace, key).await { - None => return, - Some(m) => m, - }; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::delete() - .from_table(KeyValueIden::Table) - .cond_where( - Cond::all() - .add(Expr::col(KeyValueIden::Namespace).eq(namespace)) - .add(Expr::col(KeyValueIden::Key).eq(key)), - ) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params()).expect("Failed to delete PluginKeyValue"); - emit_deleted_model(app_handle, &AnyModel::KeyValue(kv.to_owned()), update_source); -} - -pub async fn list_key_values_raw(app_handle: &AppHandle) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(KeyValueIden::Table) - .column(Asterisk) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn get_key_value_raw( - app_handle: &AppHandle, - namespace: &str, - key: &str, -) -> Option { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(KeyValueIden::Table) - .column(Asterisk) - .cond_where( - Cond::all() - .add(Expr::col(KeyValueIden::Namespace).eq(namespace)) - .add(Expr::col(KeyValueIden::Key).eq(key)), - ) - .build_rusqlite(SqliteQueryBuilder); - - db.query_row(sql.as_str(), &*params.as_params(), |row| row.try_into()).ok() -} - -pub async fn get_plugin_key_value( - app_handle: &AppHandle, - plugin_name: &str, - key: &str, -) -> Option { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(PluginKeyValueIden::Table) - .column(Asterisk) - .cond_where( - Cond::all() - .add(Expr::col(PluginKeyValueIden::PluginName).eq(plugin_name)) - .add(Expr::col(PluginKeyValueIden::Key).eq(key)), - ) - .build_rusqlite(SqliteQueryBuilder); - - db.query_row(sql.as_str(), &*params.as_params(), |row| row.try_into()).ok() -} - -pub async fn set_plugin_key_value( - app_handle: &AppHandle, - plugin_name: &str, - key: &str, - value: &str, -) -> (PluginKeyValue, bool) { - let existing = get_plugin_key_value(app_handle, plugin_name, key).await; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::insert() - .into_table(PluginKeyValueIden::Table) - .columns([ - PluginKeyValueIden::CreatedAt, - PluginKeyValueIden::UpdatedAt, - PluginKeyValueIden::PluginName, - PluginKeyValueIden::Key, - PluginKeyValueIden::Value, - ]) - .values_panic([ - CurrentTimestamp.into(), - CurrentTimestamp.into(), - plugin_name.into(), - key.into(), - value.into(), - ]) - .on_conflict( - OnConflict::new() - .update_columns([PluginKeyValueIden::UpdatedAt, PluginKeyValueIden::Value]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str()).expect("Failed to prepare PluginKeyValue upsert"); - let m: PluginKeyValue = stmt - .query_row(&*params.as_params(), |row| row.try_into()) - .expect("Failed to upsert KeyValue"); - (m, existing.is_none()) -} - -pub async fn delete_plugin_key_value( - app_handle: &AppHandle, - plugin_name: &str, - key: &str, -) -> bool { - if let None = get_plugin_key_value(app_handle, plugin_name, key).await { - return false; - } - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::delete() - .from_table(PluginKeyValueIden::Table) - .cond_where( - Cond::all() - .add(Expr::col(PluginKeyValueIden::PluginName).eq(plugin_name)) - .add(Expr::col(PluginKeyValueIden::Key).eq(key)), - ) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str()).unwrap(); - stmt.execute(&*params.as_params()).expect("Failed to delete PluginKeyValue"); - true -} - -pub async fn list_workspaces(app_handle: &AppHandle) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(WorkspaceIden::Table) - .column(Asterisk) - .order_by(WorkspaceIden::Name, Order::Asc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn list_workspace_metas( - app_handle: &AppHandle, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(WorkspaceMetaIden::Table) - .column(Asterisk) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn get_workspace(app_handle: &AppHandle, id: &str) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(WorkspaceIden::Table) - .column(Asterisk) - .cond_where(Expr::col(WorkspaceIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) -} - -pub async fn get_workspace_meta( - app_handle: &AppHandle, - workspace: &Workspace, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(WorkspaceMetaIden::Table) - .column(Asterisk) - .cond_where(Expr::col(WorkspaceMetaIden::WorkspaceId).eq(&workspace.id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into()).optional()?) -} - -pub async fn get_or_create_workspace_meta( - app_handle: &AppHandle, - workspace: &Workspace, - update_source: &UpdateSource, -) -> Result { - let workspace_meta = get_workspace_meta(app_handle, workspace).await?; - if let Some(m) = workspace_meta { - return Ok(m); - } - - upsert_workspace_meta( - app_handle, - WorkspaceMeta { - workspace_id: workspace.to_owned().id, - ..Default::default() - }, - update_source, - ) - .await -} - -pub async fn exists_workspace(app_handle: &AppHandle, id: &str) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(WorkspaceIden::Table) - .column(Asterisk) - .cond_where(Expr::col(WorkspaceIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.exists(&*params.as_params())?) -} - -pub async fn upsert_workspace( - app_handle: &AppHandle, - workspace: Workspace, - update_source: &UpdateSource, -) -> Result { - let id = match workspace.id.as_str() { - "" => generate_model_id(ModelType::TypeWorkspace), - _ => workspace.id.to_string(), - }; - let trimmed_name = workspace.name.trim(); - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::insert() - .into_table(WorkspaceIden::Table) - .columns([ - WorkspaceIden::Id, - WorkspaceIden::CreatedAt, - WorkspaceIden::UpdatedAt, - WorkspaceIden::Name, - WorkspaceIden::Description, - WorkspaceIden::SettingFollowRedirects, - WorkspaceIden::SettingRequestTimeout, - WorkspaceIden::SettingValidateCertificates, - ]) - .values_panic([ - id.as_str().into(), - timestamp_for_upsert(update_source, workspace.created_at).into(), - timestamp_for_upsert(update_source, workspace.updated_at).into(), - trimmed_name.into(), - workspace.description.into(), - workspace.setting_follow_redirects.into(), - workspace.setting_request_timeout.into(), - workspace.setting_validate_certificates.into(), - ]) - .on_conflict( - OnConflict::column(GrpcRequestIden::Id) - .update_columns([ - WorkspaceIden::UpdatedAt, - WorkspaceIden::Name, - WorkspaceIden::Description, - WorkspaceIden::SettingRequestTimeout, - WorkspaceIden::SettingFollowRedirects, - WorkspaceIden::SettingRequestTimeout, - WorkspaceIden::SettingValidateCertificates, - ]) - .values([(WorkspaceIden::UpdatedAt, CurrentTimestamp.into())]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(&sql)?; - let m: Workspace = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::Workspace(m.to_owned()), update_source); - Ok(m) -} - -pub async fn upsert_workspace_meta( - app_handle: &AppHandle, - workspace_meta: WorkspaceMeta, - update_source: &UpdateSource, -) -> Result { - let id = match workspace_meta.id.as_str() { - "" => generate_model_id(ModelType::TypeWorkspaceMeta), - _ => workspace_meta.id.to_string(), - }; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::insert() - .into_table(WorkspaceMetaIden::Table) - .columns([ - WorkspaceMetaIden::Id, - WorkspaceMetaIden::WorkspaceId, - WorkspaceMetaIden::CreatedAt, - WorkspaceMetaIden::UpdatedAt, - WorkspaceMetaIden::SettingSyncDir, - ]) - .values_panic([ - id.as_str().into(), - workspace_meta.workspace_id.into(), - timestamp_for_upsert(update_source, workspace_meta.created_at).into(), - timestamp_for_upsert(update_source, workspace_meta.updated_at).into(), - workspace_meta.setting_sync_dir.into(), - ]) - .on_conflict( - OnConflict::column(GrpcRequestIden::Id) - .update_columns([ - WorkspaceMetaIden::UpdatedAt, - WorkspaceMetaIden::SettingSyncDir, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(&sql)?; - let m: WorkspaceMeta = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::WorkspaceMeta(m.to_owned()), update_source); - Ok(m) -} - -pub async fn delete_workspace( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let workspace = get_workspace(app_handle, id).await?; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::delete() - .from_table(WorkspaceIden::Table) - .cond_where(Expr::col(WorkspaceIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params())?; - - for r in list_responses_by_workspace_id(app_handle, id).await? { - delete_http_response(app_handle, &r.id, update_source).await?; - } - - emit_deleted_model(app_handle, &AnyModel::Workspace(workspace.to_owned()), update_source); - Ok(workspace) -} - -pub async fn get_cookie_jar(app_handle: &AppHandle, id: &str) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(CookieJarIden::Table) - .column(Asterisk) - .cond_where(Expr::col(CookieJarIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) -} - -pub async fn list_cookie_jars( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(CookieJarIden::Table) - .column(Asterisk) - .cond_where(Expr::col(CookieJarIden::WorkspaceId).eq(workspace_id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn delete_cookie_jar( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let cookie_jar = get_cookie_jar(app_handle, id).await?; - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::delete() - .from_table(CookieJarIden::Table) - .cond_where(Expr::col(WorkspaceIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params())?; - - emit_deleted_model(app_handle, &AnyModel::CookieJar(cookie_jar.to_owned()), update_source); - Ok(cookie_jar) -} - -pub async fn duplicate_grpc_request( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let mut request = match get_grpc_request(app_handle, id).await? { - Some(r) => r, - None => { - return Err(ModelNotFound(id.to_string())); - } - }; - request.sort_priority = request.sort_priority + 0.001; - request.id = "".to_string(); - upsert_grpc_request(app_handle, request, update_source).await -} - -pub async fn delete_grpc_request( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let grpc_request = match get_grpc_request(app_handle, id).await? { - Some(r) => r, - None => { - return Err(ModelNotFound(id.to_string())); - } - }; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::delete() - .from_table(GrpcRequestIden::Table) - .cond_where(Expr::col(GrpcRequestIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params())?; - - emit_deleted_model(app_handle, &AnyModel::GrpcRequest(grpc_request.to_owned()), update_source); - Ok(grpc_request) -} - -pub async fn upsert_grpc_request( - app_handle: &AppHandle, - request: GrpcRequest, - update_source: &UpdateSource, -) -> Result { - let id = match request.id.as_str() { - "" => generate_model_id(ModelType::TypeGrpcRequest), - _ => request.id.to_string(), - }; - let trimmed_name = request.name.trim(); - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::insert() - .into_table(GrpcRequestIden::Table) - .columns([ - GrpcRequestIden::Id, - GrpcRequestIden::CreatedAt, - GrpcRequestIden::UpdatedAt, - GrpcRequestIden::Name, - GrpcRequestIden::Description, - GrpcRequestIden::WorkspaceId, - GrpcRequestIden::FolderId, - GrpcRequestIden::SortPriority, - GrpcRequestIden::Url, - GrpcRequestIden::Service, - GrpcRequestIden::Method, - GrpcRequestIden::Message, - GrpcRequestIden::AuthenticationType, - GrpcRequestIden::Authentication, - GrpcRequestIden::Metadata, - ]) - .values_panic([ - id.into(), - timestamp_for_upsert(update_source, request.created_at).into(), - timestamp_for_upsert(update_source, request.updated_at).into(), - trimmed_name.into(), - request.description.into(), - request.workspace_id.into(), - request.folder_id.as_ref().map(|s| s.as_str()).into(), - request.sort_priority.into(), - request.url.into(), - request.service.as_ref().map(|s| s.as_str()).into(), - request.method.as_ref().map(|s| s.as_str()).into(), - request.message.into(), - request.authentication_type.as_ref().map(|s| s.as_str()).into(), - serde_json::to_string(&request.authentication)?.into(), - serde_json::to_string(&request.metadata)?.into(), - ]) - .on_conflict( - OnConflict::column(GrpcRequestIden::Id) - .update_columns([ - GrpcRequestIden::UpdatedAt, - GrpcRequestIden::WorkspaceId, - GrpcRequestIden::Name, - GrpcRequestIden::Description, - GrpcRequestIden::FolderId, - GrpcRequestIden::SortPriority, - GrpcRequestIden::Url, - GrpcRequestIden::Service, - GrpcRequestIden::Method, - GrpcRequestIden::Message, - GrpcRequestIden::AuthenticationType, - GrpcRequestIden::Authentication, - GrpcRequestIden::Metadata, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: GrpcRequest = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::GrpcRequest(m.to_owned()), update_source); - Ok(m) -} - -pub async fn get_grpc_request( - app_handle: &AppHandle, - id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(GrpcRequestIden::Table) - .column(Asterisk) - .cond_where(Expr::col(GrpcRequestIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into()).optional()?) -} - -pub async fn list_grpc_requests( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(GrpcRequestIden::Table) - .cond_where(Expr::col(GrpcRequestIden::WorkspaceId).eq(workspace_id)) - .column(Asterisk) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn upsert_grpc_connection( - app_handle: &AppHandle, - connection: &GrpcConnection, - update_source: &UpdateSource, -) -> Result { - let connections = - list_grpc_connections_for_request(app_handle, connection.request_id.as_str()).await?; - for c in connections.iter().skip(MAX_HISTORY_ITEMS - 1) { - debug!("Deleting old grpc connection {}", c.id); - delete_grpc_connection(app_handle, c.id.as_str(), update_source).await?; - } - - let id = match connection.id.as_str() { - "" => generate_model_id(ModelType::TypeGrpcConnection), - _ => connection.id.to_string(), - }; - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::insert() - .into_table(GrpcConnectionIden::Table) - .columns([ - GrpcConnectionIden::Id, - GrpcConnectionIden::CreatedAt, - GrpcConnectionIden::UpdatedAt, - GrpcConnectionIden::WorkspaceId, - GrpcConnectionIden::RequestId, - GrpcConnectionIden::Service, - GrpcConnectionIden::Method, - GrpcConnectionIden::Elapsed, - GrpcConnectionIden::State, - GrpcConnectionIden::Status, - GrpcConnectionIden::Error, - GrpcConnectionIden::Trailers, - GrpcConnectionIden::Url, - ]) - .values_panic([ - id.as_str().into(), - timestamp_for_upsert(update_source, connection.created_at).into(), - timestamp_for_upsert(update_source, connection.updated_at).into(), - connection.workspace_id.as_str().into(), - connection.request_id.as_str().into(), - connection.service.as_str().into(), - connection.method.as_str().into(), - connection.elapsed.into(), - serde_json::to_value(&connection.state)?.as_str().into(), - connection.status.into(), - connection.error.as_ref().map(|s| s.as_str()).into(), - serde_json::to_string(&connection.trailers)?.into(), - connection.url.as_str().into(), - ]) - .on_conflict( - OnConflict::column(GrpcConnectionIden::Id) - .update_columns([ - GrpcConnectionIden::UpdatedAt, - GrpcConnectionIden::Service, - GrpcConnectionIden::Method, - GrpcConnectionIden::Elapsed, - GrpcConnectionIden::Status, - GrpcConnectionIden::State, - GrpcConnectionIden::Error, - GrpcConnectionIden::Trailers, - GrpcConnectionIden::Url, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: GrpcConnection = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::GrpcConnection(m.to_owned()), update_source); - Ok(m) -} - -pub async fn get_grpc_connection( - app_handle: &AppHandle, - id: &str, -) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(GrpcConnectionIden::Table) - .column(Asterisk) - .cond_where(Expr::col(GrpcConnectionIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) -} - -pub async fn list_grpc_connections_for_workspace( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(GrpcConnectionIden::Table) - .cond_where(Expr::col(GrpcConnectionIden::WorkspaceId).eq(workspace_id)) - .column(Asterisk) - .order_by(GrpcConnectionIden::CreatedAt, Order::Desc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn list_grpc_connections_for_request( - app_handle: &AppHandle, - request_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(GrpcConnectionIden::Table) - .cond_where(Expr::col(GrpcConnectionIden::RequestId).eq(request_id)) - .column(Asterisk) - .order_by(GrpcConnectionIden::CreatedAt, Order::Desc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn delete_grpc_connection( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let m = get_grpc_connection(app_handle, id).await?; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::delete() - .from_table(GrpcConnectionIden::Table) - .cond_where(Expr::col(GrpcConnectionIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - - db.execute(sql.as_str(), &*params.as_params())?; - emit_deleted_model(app_handle, &AnyModel::GrpcConnection(m.to_owned()), update_source); - Ok(m) -} - -pub async fn delete_all_grpc_connections( - app_handle: &AppHandle, - request_id: &str, - update_source: &UpdateSource, -) -> Result<()> { - for r in list_grpc_connections_for_request(app_handle, request_id).await? { - delete_grpc_connection(app_handle, &r.id, update_source).await?; - } - Ok(()) -} - -pub async fn delete_all_grpc_connections_for_workspace( - app_handle: &AppHandle, - workspace_id: &str, - update_source: &UpdateSource, -) -> Result<()> { - for r in list_grpc_connections_for_workspace(app_handle, workspace_id).await? { - delete_grpc_connection(app_handle, &r.id, update_source).await?; - } - Ok(()) -} - -pub async fn upsert_grpc_event( - app_handle: &AppHandle, - event: &GrpcEvent, - update_source: &UpdateSource, -) -> Result { - let id = match event.id.as_str() { - "" => generate_model_id(ModelType::TypeGrpcEvent), - _ => event.id.to_string(), - }; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::insert() - .into_table(GrpcEventIden::Table) - .columns([ - GrpcEventIden::Id, - GrpcEventIden::CreatedAt, - GrpcEventIden::UpdatedAt, - GrpcEventIden::WorkspaceId, - GrpcEventIden::RequestId, - GrpcEventIden::ConnectionId, - GrpcEventIden::Content, - GrpcEventIden::EventType, - GrpcEventIden::Metadata, - GrpcEventIden::Status, - GrpcEventIden::Error, - ]) - .values_panic([ - id.as_str().into(), - timestamp_for_upsert(update_source, event.created_at).into(), - timestamp_for_upsert(update_source, event.updated_at).into(), - event.workspace_id.as_str().into(), - event.request_id.as_str().into(), - event.connection_id.as_str().into(), - event.content.as_str().into(), - serde_json::to_string(&event.event_type)?.into(), - serde_json::to_string(&event.metadata)?.into(), - event.status.into(), - event.error.as_ref().map(|s| s.as_str()).into(), - ]) - .on_conflict( - OnConflict::column(GrpcEventIden::Id) - .update_columns([ - GrpcEventIden::UpdatedAt, - GrpcEventIden::Content, - GrpcEventIden::EventType, - GrpcEventIden::Metadata, - GrpcEventIden::Status, - GrpcEventIden::Error, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: GrpcEvent = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::GrpcEvent(m.to_owned()), update_source); - Ok(m) -} - -pub async fn get_grpc_event(app_handle: &AppHandle, id: &str) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(GrpcEventIden::Table) - .column(Asterisk) - .cond_where(Expr::col(GrpcEventIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) -} - -pub async fn list_grpc_events( - app_handle: &AppHandle, - connection_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(GrpcEventIden::Table) - .cond_where(Expr::col(GrpcEventIden::ConnectionId).eq(connection_id)) - .column(Asterisk) - .order_by(GrpcEventIden::CreatedAt, Order::Asc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn delete_websocket_request( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let request = match get_websocket_request(app_handle, id).await? { - Some(r) => r, - None => { - return Err(ModelNotFound(id.to_string())); - } - }; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::delete() - .from_table(WebsocketRequestIden::Table) - .cond_where(Expr::col(WebsocketRequestIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params())?; - - emit_deleted_model(app_handle, &AnyModel::WebsocketRequest(request.to_owned()), update_source); - Ok(request) -} - -pub async fn delete_websocket_connection( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let m = get_websocket_connection(app_handle, id).await?; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::delete() - .from_table(WebsocketConnectionIden::Table) - .cond_where(Expr::col(WebsocketConnectionIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params())?; - - emit_deleted_model(app_handle, &AnyModel::WebsocketConnection(m.to_owned()), update_source); - Ok(m) -} - -pub async fn delete_all_websocket_connections( - app_handle: &AppHandle, - request_id: &str, - update_source: &UpdateSource, -) -> Result<()> { - for c in list_websocket_connections_for_request(app_handle, request_id).await? { - delete_websocket_connection(app_handle, &c.id, update_source).await?; - } - Ok(()) -} - -pub async fn delete_all_websocket_connections_for_workspace( - app_handle: &AppHandle, - workspace_id: &str, - update_source: &UpdateSource, -) -> Result<()> { - for c in list_websocket_connections_for_workspace(app_handle, workspace_id).await? { - delete_websocket_connection(app_handle, &c.id, update_source).await?; - } - Ok(()) -} - -pub async fn get_websocket_connection( - app_handle: &AppHandle, - id: &str, -) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(WebsocketConnectionIden::Table) - .column(Asterisk) - .cond_where(Expr::col(WebsocketConnectionIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) -} - -pub async fn upsert_websocket_event( - app_handle: &AppHandle, - event: WebsocketEvent, - update_source: &UpdateSource, -) -> Result { - let id = match event.id.as_str() { - "" => generate_model_id(ModelType::TypeWebSocketEvent), - _ => event.id.to_string(), - }; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::insert() - .into_table(WebsocketEventIden::Table) - .columns([ - WebsocketEventIden::Id, - WebsocketEventIden::CreatedAt, - WebsocketEventIden::UpdatedAt, - WebsocketEventIden::WorkspaceId, - WebsocketEventIden::ConnectionId, - WebsocketEventIden::RequestId, - WebsocketEventIden::MessageType, - WebsocketEventIden::IsServer, - WebsocketEventIden::Message, - ]) - .values_panic([ - id.into(), - timestamp_for_upsert(update_source, event.created_at).into(), - timestamp_for_upsert(update_source, event.updated_at).into(), - event.workspace_id.into(), - event.connection_id.into(), - event.request_id.into(), - serde_json::to_string(&event.message_type)?.into(), - event.is_server.into(), - event.message.into(), - ]) - .on_conflict( - OnConflict::column(WebsocketEventIden::Id) - .update_columns([ - WebsocketEventIden::UpdatedAt, - WebsocketEventIden::MessageType, - WebsocketEventIden::IsServer, - WebsocketEventIden::Message, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: WebsocketEvent = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::WebsocketEvent(m.to_owned()), update_source); - Ok(m) -} - -pub async fn duplicate_websocket_request( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let mut request = match get_websocket_request(app_handle, id).await? { - None => return Err(ModelNotFound(id.to_string())), - Some(r) => r, - }; - request.id = "".to_string(); - request.sort_priority = request.sort_priority + 0.001; - upsert_websocket_request(app_handle, request, update_source).await -} - -pub async fn upsert_websocket_request( - app_handle: &AppHandle, - request: WebsocketRequest, - update_source: &UpdateSource, -) -> Result { - let id = match request.id.as_str() { - "" => generate_model_id(ModelType::TypeWebsocketRequest), - _ => request.id.to_string(), - }; - let trimmed_name = request.name.trim(); - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::insert() - .into_table(WebsocketRequestIden::Table) - .columns([ - WebsocketRequestIden::Id, - WebsocketRequestIden::CreatedAt, - WebsocketRequestIden::UpdatedAt, - WebsocketRequestIden::WorkspaceId, - WebsocketRequestIden::FolderId, - WebsocketRequestIden::Authentication, - WebsocketRequestIden::AuthenticationType, - WebsocketRequestIden::Description, - WebsocketRequestIden::Headers, - WebsocketRequestIden::Message, - WebsocketRequestIden::Name, - WebsocketRequestIden::SortPriority, - WebsocketRequestIden::Url, - WebsocketRequestIden::UrlParameters, - ]) - .values_panic([ - id.into(), - timestamp_for_upsert(update_source, request.created_at).into(), - timestamp_for_upsert(update_source, request.updated_at).into(), - request.workspace_id.into(), - request.folder_id.as_ref().map(|s| s.as_str()).into(), - serde_json::to_string(&request.authentication)?.into(), - request.authentication_type.as_ref().map(|s| s.as_str()).into(), - request.description.into(), - serde_json::to_string(&request.headers)?.into(), - request.message.into(), - trimmed_name.into(), - request.sort_priority.into(), - request.url.into(), - serde_json::to_string(&request.url_parameters)?.into(), - ]) - .on_conflict( - OnConflict::column(WebsocketRequestIden::Id) - .update_columns([ - WebsocketRequestIden::UpdatedAt, - WebsocketRequestIden::WorkspaceId, - WebsocketRequestIden::FolderId, - WebsocketRequestIden::Authentication, - WebsocketRequestIden::AuthenticationType, - WebsocketRequestIden::Description, - WebsocketRequestIden::Headers, - WebsocketRequestIden::Message, - WebsocketRequestIden::Name, - WebsocketRequestIden::SortPriority, - WebsocketRequestIden::Url, - WebsocketRequestIden::UrlParameters, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: WebsocketRequest = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::WebsocketRequest(m.to_owned()), update_source); - Ok(m) -} - -pub async fn list_websocket_connections_for_workspace( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(WebsocketConnectionIden::Table) - .cond_where(Expr::col(WebsocketConnectionIden::WorkspaceId).eq(workspace_id)) - .column(Asterisk) - .order_by(WebsocketConnectionIden::CreatedAt, Order::Desc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn list_websocket_connections_for_request( - app_handle: &AppHandle, - request_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(WebsocketConnectionIden::Table) - .cond_where(Expr::col(WebsocketConnectionIden::RequestId).eq(request_id)) - .column(Asterisk) - .order_by(WebsocketConnectionIden::CreatedAt, Order::Desc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn upsert_websocket_connection( - app_handle: &AppHandle, - connection: &WebsocketConnection, - update_source: &UpdateSource, -) -> Result { - let connections = - list_websocket_connections_for_request(app_handle, connection.request_id.as_str()).await?; - for c in connections.iter().skip(MAX_HISTORY_ITEMS - 1) { - debug!("Deleting old websocket connection {}", c.id); - delete_websocket_connection(app_handle, c.id.as_str(), update_source).await?; - } - - let id = match connection.id.as_str() { - "" => generate_model_id(ModelType::TypeWebSocketConnection), - _ => connection.id.to_string(), - }; - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::insert() - .into_table(WebsocketConnectionIden::Table) - .columns([ - WebsocketConnectionIden::Id, - WebsocketConnectionIden::CreatedAt, - WebsocketConnectionIden::UpdatedAt, - WebsocketConnectionIden::WorkspaceId, - WebsocketConnectionIden::RequestId, - WebsocketConnectionIden::Elapsed, - WebsocketConnectionIden::Error, - WebsocketConnectionIden::Headers, - WebsocketConnectionIden::State, - WebsocketConnectionIden::Status, - WebsocketConnectionIden::Url, - ]) - .values_panic([ - id.as_str().into(), - timestamp_for_upsert(update_source, connection.created_at).into(), - timestamp_for_upsert(update_source, connection.updated_at).into(), - connection.workspace_id.as_str().into(), - connection.request_id.as_str().into(), - connection.elapsed.into(), - connection.error.as_ref().map(|s| s.as_str()).into(), - serde_json::to_string(&connection.headers)?.into(), - serde_json::to_value(&connection.state)?.as_str().into(), - connection.status.into(), - connection.url.as_str().into(), - ]) - .on_conflict( - OnConflict::column(WebsocketConnectionIden::Id) - .update_columns([ - WebsocketConnectionIden::UpdatedAt, - WebsocketConnectionIden::Elapsed, - WebsocketConnectionIden::Error, - WebsocketConnectionIden::Headers, - WebsocketConnectionIden::State, - WebsocketConnectionIden::Status, - WebsocketConnectionIden::Url, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: WebsocketConnection = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::WebsocketConnection(m.to_owned()), update_source); - Ok(m) -} - -pub async fn get_websocket_request( - app_handle: &AppHandle, - id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(WebsocketRequestIden::Table) - .column(Asterisk) - .cond_where(Expr::col(WebsocketRequestIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into()).optional()?) -} - -pub async fn list_websocket_requests( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(WebsocketRequestIden::Table) - .cond_where(Expr::col(WebsocketRequestIden::WorkspaceId).eq(workspace_id)) - .column(Asterisk) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn list_websocket_events( - app_handle: &AppHandle, - connection_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(WebsocketEventIden::Table) - .cond_where(Expr::col(WebsocketEventIden::ConnectionId).eq(connection_id)) - .column(Asterisk) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn upsert_cookie_jar( - app_handle: &AppHandle, - cookie_jar: &CookieJar, - update_source: &UpdateSource, -) -> Result { - let id = match cookie_jar.id.as_str() { - "" => generate_model_id(ModelType::TypeCookieJar), - _ => cookie_jar.id.to_string(), - }; - let trimmed_name = cookie_jar.name.trim(); - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::insert() - .into_table(CookieJarIden::Table) - .columns([ - CookieJarIden::Id, - CookieJarIden::CreatedAt, - CookieJarIden::UpdatedAt, - CookieJarIden::WorkspaceId, - CookieJarIden::Name, - CookieJarIden::Cookies, - ]) - .values_panic([ - id.as_str().into(), - timestamp_for_upsert(update_source, cookie_jar.created_at).into(), - timestamp_for_upsert(update_source, cookie_jar.updated_at).into(), - cookie_jar.workspace_id.as_str().into(), - trimmed_name.into(), - serde_json::to_string(&cookie_jar.cookies)?.into(), - ]) - .on_conflict( - OnConflict::column(GrpcEventIden::Id) - .update_columns([ - CookieJarIden::UpdatedAt, - CookieJarIden::Name, - CookieJarIden::Cookies, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: CookieJar = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::CookieJar(m.to_owned()), update_source); - Ok(m) -} - -pub async fn ensure_base_environment( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result<()> { - let environments = list_environments(app_handle, workspace_id).await?; - let base_environment = - environments.iter().find(|e| e.environment_id == None && e.workspace_id == workspace_id); - - if let None = base_environment { - info!("Creating base environment for {workspace_id}"); - upsert_environment( - app_handle, - Environment { - workspace_id: workspace_id.to_string(), - name: "Global Variables".to_string(), - ..Default::default() - }, - &UpdateSource::Background, - ) - .await?; - } - - Ok(()) -} - -pub async fn list_environments( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result> { - let environments: Vec = { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(EnvironmentIden::Table) - .cond_where(Expr::col(EnvironmentIden::WorkspaceId).eq(workspace_id)) - .column(Asterisk) - .order_by(EnvironmentIden::Name, Order::Asc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - items.map(|v| v.unwrap()).collect() - }; - - Ok(environments) -} - -pub async fn delete_environment( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let env = get_environment(app_handle, id).await?; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::delete() - .from_table(EnvironmentIden::Table) - .cond_where(Expr::col(EnvironmentIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - - db.execute(sql.as_str(), &*params.as_params())?; - - emit_deleted_model(app_handle, &AnyModel::Environment(env.to_owned()), update_source); - Ok(env) -} - -const SETTINGS_ID: &str = "default"; - -async fn get_settings(app_handle: &AppHandle) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(SettingsIden::Table) - .column(Asterisk) - .cond_where(Expr::col(SettingsIden::Id).eq(SETTINGS_ID)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into()).optional()?) -} - -pub async fn get_or_create_settings(app_handle: &AppHandle) -> Settings { - match get_settings(app_handle).await { - Ok(Some(settings)) => return settings, - Err(e) => panic!("Failed to get settings {e:?}"), - Ok(None) => {} - }; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::insert() - .into_table(SettingsIden::Table) - .columns([SettingsIden::Id]) - .values_panic([SETTINGS_ID.into()]) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str()).expect("Failed to prepare Settings insert"); - stmt.query_row(&*params.as_params(), |row| row.try_into()).expect("Failed to insert Settings") -} - -pub async fn update_settings( - app_handle: &AppHandle, - settings: Settings, - update_source: &UpdateSource, -) -> Result { - // Correct for the bug where created_at was being updated by mistake - let created_at = if settings.created_at > settings.updated_at { - settings.updated_at - } else { - settings.created_at - }; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::update() - .table(SettingsIden::Table) - .cond_where(Expr::col(SettingsIden::Id).eq("default")) - .values([ - (SettingsIden::Id, "default".into()), - (SettingsIden::CreatedAt, created_at.into()), - (SettingsIden::UpdatedAt, CurrentTimestamp.into()), - (SettingsIden::Appearance, settings.appearance.as_str().into()), - (SettingsIden::ThemeDark, settings.theme_dark.as_str().into()), - (SettingsIden::ThemeLight, settings.theme_light.as_str().into()), - (SettingsIden::UpdateChannel, settings.update_channel.into()), - (SettingsIden::InterfaceFontSize, settings.interface_font_size.into()), - (SettingsIden::InterfaceScale, settings.interface_scale.into()), - (SettingsIden::EditorFontSize, settings.editor_font_size.into()), - (SettingsIden::EditorKeymap, settings.editor_keymap.to_string().into()), - (SettingsIden::EditorSoftWrap, settings.editor_soft_wrap.into()), - (SettingsIden::OpenWorkspaceNewWindow, settings.open_workspace_new_window.into()), - ( - SettingsIden::Proxy, - (match settings.proxy { - None => None, - Some(p) => Some(serde_json::to_string(&p)?), - }) - .into(), - ), - ]) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: Settings = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::Settings(m.to_owned()), update_source); - Ok(m) -} - -pub async fn upsert_environment( - app_handle: &AppHandle, - environment: Environment, - update_source: &UpdateSource, -) -> Result { - let id = match environment.id.as_str() { - "" => generate_model_id(ModelType::TypeEnvironment), - _ => environment.id.to_string(), - }; - let trimmed_name = environment.name.trim(); - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::insert() - .into_table(EnvironmentIden::Table) - .columns([ - EnvironmentIden::Id, - EnvironmentIden::CreatedAt, - EnvironmentIden::UpdatedAt, - EnvironmentIden::EnvironmentId, - EnvironmentIden::WorkspaceId, - EnvironmentIden::Name, - EnvironmentIden::Variables, - ]) - .values_panic([ - id.as_str().into(), - timestamp_for_upsert(update_source, environment.created_at).into(), - timestamp_for_upsert(update_source, environment.updated_at).into(), - environment.environment_id.into(), - environment.workspace_id.into(), - trimmed_name.into(), - serde_json::to_string(&environment.variables)?.into(), - ]) - .on_conflict( - OnConflict::column(EnvironmentIden::Id) - .update_columns([ - EnvironmentIden::UpdatedAt, - EnvironmentIden::Name, - EnvironmentIden::Variables, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: Environment = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::Environment(m.to_owned()), update_source); - Ok(m) -} - -pub async fn get_environment( - app_handle: &AppHandle, - id: &str, -) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(EnvironmentIden::Table) - .column(Asterisk) - .cond_where(Expr::col(EnvironmentIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) -} - -pub async fn get_base_environment( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(EnvironmentIden::Table) - .column(Asterisk) - .cond_where( - Cond::all() - .add(Expr::col(EnvironmentIden::WorkspaceId).eq(workspace_id)) - .add(Expr::col(EnvironmentIden::EnvironmentId).is_null()), - ) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) -} - -pub async fn get_plugin(app_handle: &AppHandle, id: &str) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(PluginIden::Table) - .column(Asterisk) - .cond_where(Expr::col(EnvironmentIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) -} - -pub async fn list_plugins(app_handle: &AppHandle) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(PluginIden::Table) - .column(Asterisk) - .order_by(PluginIden::CreatedAt, Order::Desc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn upsert_plugin( - app_handle: &AppHandle, - plugin: Plugin, - update_source: &UpdateSource, -) -> Result { - let id = match plugin.id.as_str() { - "" => generate_model_id(ModelType::TypePlugin), - _ => plugin.id.to_string(), - }; - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::insert() - .into_table(PluginIden::Table) - .columns([ - PluginIden::Id, - PluginIden::CreatedAt, - PluginIden::UpdatedAt, - PluginIden::CheckedAt, - PluginIden::Directory, - PluginIden::Url, - PluginIden::Enabled, - ]) - .values_panic([ - id.as_str().into(), - timestamp_for_upsert(update_source, plugin.created_at).into(), - timestamp_for_upsert(update_source, plugin.updated_at).into(), - plugin.checked_at.into(), - plugin.directory.into(), - plugin.url.into(), - plugin.enabled.into(), - ]) - .on_conflict( - OnConflict::column(PluginIden::Id) - .update_columns([ - PluginIden::UpdatedAt, - PluginIden::CheckedAt, - PluginIden::Directory, - PluginIden::Url, - PluginIden::Enabled, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: Plugin = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::Plugin(m.to_owned()), update_source); - Ok(m) -} - -pub async fn delete_plugin( - app_handle: &AppHandle, - id: &str, - - update_source: &UpdateSource, -) -> Result { - let plugin = get_plugin(app_handle, id).await?; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::delete() - .from_table(PluginIden::Table) - .cond_where(Expr::col(PluginIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params())?; - - emit_deleted_model(app_handle, &AnyModel::Plugin(plugin.to_owned()), update_source); - Ok(plugin) -} - -pub async fn get_folder(app_handle: &AppHandle, id: &str) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(FolderIden::Table) - .column(Asterisk) - .cond_where(Expr::col(FolderIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) -} - -pub async fn list_folders( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(FolderIden::Table) - .cond_where(Expr::col(FolderIden::WorkspaceId).eq(workspace_id)) - .column(Asterisk) - .order_by(FolderIden::CreatedAt, Order::Desc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn delete_folder( - app_handle: &AppHandle, - id: &str, - - update_source: &UpdateSource, -) -> Result { - let folder = get_folder(app_handle, id).await?; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::delete() - .from_table(FolderIden::Table) - .cond_where(Expr::col(FolderIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params())?; - - emit_deleted_model(app_handle, &AnyModel::Folder(folder.to_owned()), update_source); - Ok(folder) -} - -pub async fn upsert_folder( - app_handle: &AppHandle, - folder: Folder, - - update_source: &UpdateSource, -) -> Result { - let id = match folder.id.as_str() { - "" => generate_model_id(ModelType::TypeFolder), - _ => folder.id.to_string(), - }; - let trimmed_name = folder.name.trim(); - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::insert() - .into_table(FolderIden::Table) - .columns([ - FolderIden::Id, - FolderIden::CreatedAt, - FolderIden::UpdatedAt, - FolderIden::WorkspaceId, - FolderIden::FolderId, - FolderIden::Name, - FolderIden::Description, - FolderIden::SortPriority, - ]) - .values_panic([ - id.as_str().into(), - timestamp_for_upsert(update_source, folder.created_at).into(), - timestamp_for_upsert(update_source, folder.updated_at).into(), - folder.workspace_id.as_str().into(), - folder.folder_id.as_ref().map(|s| s.as_str()).into(), - trimmed_name.into(), - folder.description.into(), - folder.sort_priority.into(), - ]) - .on_conflict( - OnConflict::column(GrpcEventIden::Id) - .update_columns([ - FolderIden::UpdatedAt, - FolderIden::Name, - FolderIden::Description, - FolderIden::FolderId, - FolderIden::SortPriority, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: Folder = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::Folder(m.to_owned()), update_source); - Ok(m) -} - -pub async fn duplicate_http_request( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let mut request = match get_http_request(app_handle, id).await? { - None => return Err(ModelNotFound(id.to_string())), - Some(r) => r, - }; - request.id = "".to_string(); - request.sort_priority = request.sort_priority + 0.001; - upsert_http_request(app_handle, request, update_source).await -} - -pub async fn duplicate_folder( - app_handle: &AppHandle, - src_folder: &Folder, - update_source: &UpdateSource, -) -> Result<()> { - let workspace_id = src_folder.workspace_id.as_str(); - - let http_requests = list_http_requests(app_handle, workspace_id) - .await? - .into_iter() - .filter(|m| m.folder_id.as_ref() == Some(&src_folder.id)); - - let grpc_requests = list_grpc_requests(app_handle, workspace_id) - .await? - .into_iter() - .filter(|m| m.folder_id.as_ref() == Some(&src_folder.id)); - - let folders = list_folders(app_handle, workspace_id) - .await? - .into_iter() - .filter(|m| m.folder_id.as_ref() == Some(&src_folder.id)); - - let new_folder = upsert_folder( - app_handle, - Folder { - id: "".into(), - sort_priority: src_folder.sort_priority + 0.001, - ..src_folder.clone() - }, - update_source, - ) - .await?; - - for m in http_requests { - upsert_http_request( - app_handle, - HttpRequest { - id: "".into(), - folder_id: Some(new_folder.id.clone()), - sort_priority: m.sort_priority + 0.001, - ..m - }, - update_source, - ) - .await?; - } - for m in grpc_requests { - upsert_grpc_request( - app_handle, - GrpcRequest { - id: "".into(), - folder_id: Some(new_folder.id.clone()), - sort_priority: m.sort_priority + 0.001, - ..m - }, - update_source, - ) - .await?; - } - for m in folders { - // Recurse down - Box::pin(duplicate_folder( - app_handle, - &Folder { - folder_id: Some(new_folder.id.clone()), - ..m - }, - update_source, - )) - .await?; - } - Ok(()) -} - -pub async fn upsert_http_request( - app_handle: &AppHandle, - request: HttpRequest, - update_source: &UpdateSource, -) -> Result { - let id = match request.id.as_str() { - "" => generate_model_id(ModelType::TypeHttpRequest), - _ => request.id.to_string(), - }; - let trimmed_name = request.name.trim(); - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::insert() - .into_table(HttpRequestIden::Table) - .columns([ - HttpRequestIden::Id, - HttpRequestIden::CreatedAt, - HttpRequestIden::UpdatedAt, - HttpRequestIden::WorkspaceId, - HttpRequestIden::FolderId, - HttpRequestIden::Name, - HttpRequestIden::Description, - HttpRequestIden::Url, - HttpRequestIden::UrlParameters, - HttpRequestIden::Method, - HttpRequestIden::Body, - HttpRequestIden::BodyType, - HttpRequestIden::Authentication, - HttpRequestIden::AuthenticationType, - HttpRequestIden::Headers, - HttpRequestIden::SortPriority, - ]) - .values_panic([ - id.as_str().into(), - timestamp_for_upsert(update_source, request.created_at).into(), - timestamp_for_upsert(update_source, request.updated_at).into(), - request.workspace_id.into(), - request.folder_id.as_ref().map(|s| s.as_str()).into(), - trimmed_name.into(), - request.description.into(), - request.url.into(), - serde_json::to_string(&request.url_parameters)?.into(), - request.method.into(), - serde_json::to_string(&request.body)?.into(), - request.body_type.as_ref().map(|s| s.as_str()).into(), - serde_json::to_string(&request.authentication)?.into(), - request.authentication_type.as_ref().map(|s| s.as_str()).into(), - serde_json::to_string(&request.headers)?.into(), - request.sort_priority.into(), - ]) - .on_conflict( - OnConflict::column(GrpcEventIden::Id) - .update_columns([ - HttpRequestIden::UpdatedAt, - HttpRequestIden::WorkspaceId, - HttpRequestIden::Name, - HttpRequestIden::Description, - HttpRequestIden::FolderId, - HttpRequestIden::Method, - HttpRequestIden::Headers, - HttpRequestIden::Body, - HttpRequestIden::BodyType, - HttpRequestIden::Authentication, - HttpRequestIden::AuthenticationType, - HttpRequestIden::Url, - HttpRequestIden::UrlParameters, - HttpRequestIden::SortPriority, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: HttpRequest = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::HttpRequest(m.to_owned()), update_source); - Ok(m) -} - -pub async fn list_http_requests( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(HttpRequestIden::Table) - .cond_where(Expr::col(HttpRequestIden::WorkspaceId).eq(workspace_id)) - .column(Asterisk) - .order_by(HttpRequestIden::CreatedAt, Order::Desc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn get_http_request( - app_handle: &AppHandle, - id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::select() - .from(HttpRequestIden::Table) - .column(Asterisk) - .cond_where(Expr::col(HttpRequestIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into()).optional()?) -} - -pub async fn delete_http_request( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let req = match get_http_request(app_handle, id).await? { - None => return Err(ModelNotFound(id.to_string())), - Some(r) => r, - }; - - // DB deletes will cascade but this will delete the files - delete_all_http_responses_for_request(app_handle, id, update_source).await?; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::delete() - .from_table(HttpRequestIden::Table) - .cond_where(Expr::col(HttpRequestIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params())?; - - emit_deleted_model(app_handle, &AnyModel::HttpRequest(req.to_owned()), update_source); - Ok(req) -} - -pub async fn create_default_http_response( - app_handle: &AppHandle, - request_id: &str, - update_source: &UpdateSource, -) -> Result { - create_http_response( - &app_handle, - request_id, - 0, - 0, - "", - HttpResponseState::Initialized, - 0, - None, - None, - None, - vec![], - None, - None, - update_source, - ) - .await -} - -#[allow(clippy::too_many_arguments)] -pub async fn create_http_response( - app_handle: &AppHandle, - request_id: &str, - elapsed: i64, - elapsed_headers: i64, - url: &str, - state: HttpResponseState, - status: i64, - status_reason: Option<&str>, - content_length: Option, - body_path: Option<&str>, - headers: Vec, - version: Option<&str>, - remote_addr: Option<&str>, - update_source: &UpdateSource, -) -> Result { - let responses = list_http_responses_for_request(app_handle, request_id, None).await?; - for response in responses.iter().skip(MAX_HISTORY_ITEMS - 1) { - debug!("Deleting old response {}", response.id); - delete_http_response(app_handle, response.id.as_str(), update_source).await?; - } - - let req = match get_http_request(app_handle, request_id).await? { - None => return Err(ModelNotFound(request_id.to_string())), - Some(r) => r, - }; - let id = generate_model_id(ModelType::TypeHttpResponse); - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::insert() - .into_table(HttpResponseIden::Table) - .columns([ - HttpResponseIden::Id, - HttpResponseIden::CreatedAt, - HttpResponseIden::UpdatedAt, - HttpResponseIden::RequestId, - HttpResponseIden::WorkspaceId, - HttpResponseIden::Elapsed, - HttpResponseIden::ElapsedHeaders, - HttpResponseIden::Url, - HttpResponseIden::State, - HttpResponseIden::Status, - HttpResponseIden::StatusReason, - HttpResponseIden::ContentLength, - HttpResponseIden::BodyPath, - HttpResponseIden::Headers, - HttpResponseIden::Version, - HttpResponseIden::RemoteAddr, - ]) - .values_panic([ - id.as_str().into(), - CurrentTimestamp.into(), - CurrentTimestamp.into(), - req.id.as_str().into(), - req.workspace_id.as_str().into(), - elapsed.into(), - elapsed_headers.into(), - url.into(), - serde_json::to_value(state)?.as_str().unwrap_or_default().into(), - status.into(), - status_reason.into(), - content_length.into(), - body_path.into(), - serde_json::to_string(&headers)?.into(), - version.into(), - remote_addr.into(), - ]) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: HttpResponse = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::HttpResponse(m.to_owned()), update_source); - Ok(m) -} - -pub async fn cancel_pending_websocket_connections( - app_handle: &AppHandle, -) -> Result<()> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let closed = serde_json::to_value(&WebsocketConnectionState::Closed)?; - let (sql, params) = Query::update() - .table(WebsocketConnectionIden::Table) - .values([(WebsocketConnectionIden::State, closed.as_str().into())]) - .cond_where(Expr::col(WebsocketConnectionIden::State).ne(closed.as_str())) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - stmt.execute(&*params.as_params())?; - Ok(()) -} - -pub async fn cancel_pending_grpc_connections(app: &AppHandle) -> Result<()> { - let dbm = &*app.app_handle().state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let closed = serde_json::to_value(&GrpcConnectionState::Closed)?; - let (sql, params) = Query::update() - .table(GrpcConnectionIden::Table) - .values([(GrpcConnectionIden::State, closed.as_str().into())]) - .cond_where(Expr::col(GrpcConnectionIden::State).ne(closed.as_str())) - .build_rusqlite(SqliteQueryBuilder); - - db.execute(sql.as_str(), &*params.as_params())?; - Ok(()) -} - -pub async fn cancel_pending_http_responses(app: &AppHandle) -> Result<()> { - let dbm = &*app.app_handle().state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let closed = serde_json::to_value(&GrpcConnectionState::Closed)?; - let (sql, params) = Query::update() - .table(HttpResponseIden::Table) - .values([ - (HttpResponseIden::State, closed.as_str().into()), - (HttpResponseIden::StatusReason, "Cancelled".into()), - ]) - .cond_where(Expr::col(HttpResponseIden::State).ne(closed.as_str())) - .build_rusqlite(SqliteQueryBuilder); - - db.execute(sql.as_str(), &*params.as_params())?; - Ok(()) -} - -pub async fn update_response_if_id( - app_handle: &AppHandle, - response: &HttpResponse, - update_source: &UpdateSource, -) -> Result { - if response.id.is_empty() { - Ok(response.clone()) - } else { - update_http_response(app_handle, response, update_source).await - } -} - -pub async fn update_http_response( - app_handle: &AppHandle, - response: &HttpResponse, - update_source: &UpdateSource, -) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::update() - .table(HttpResponseIden::Table) - .cond_where(Expr::col(HttpResponseIden::Id).eq(response.clone().id)) - .values([ - (HttpResponseIden::UpdatedAt, CurrentTimestamp.into()), - (HttpResponseIden::Elapsed, response.elapsed.into()), - (HttpResponseIden::Url, response.url.as_str().into()), - (HttpResponseIden::Status, response.status.into()), - ( - HttpResponseIden::StatusReason, - response.status_reason.as_ref().map(|s| s.as_str()).into(), - ), - (HttpResponseIden::ContentLength, response.content_length.into()), - (HttpResponseIden::BodyPath, response.body_path.as_ref().map(|s| s.as_str()).into()), - (HttpResponseIden::Error, response.error.as_ref().map(|s| s.as_str()).into()), - ( - HttpResponseIden::Headers, - serde_json::to_string(&response.headers).unwrap_or_default().into(), - ), - (HttpResponseIden::Version, response.version.as_ref().map(|s| s.as_str()).into()), - (HttpResponseIden::State, serde_json::to_value(&response.state)?.as_str().into()), - ( - HttpResponseIden::RemoteAddr, - response.remote_addr.as_ref().map(|s| s.as_str()).into(), - ), - ]) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: HttpResponse = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - emit_upserted_model(app_handle, &AnyModel::HttpResponse(m.to_owned()), update_source); - Ok(m) -} - -pub async fn get_http_response( - app_handle: &AppHandle, - id: &str, -) -> Result { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(HttpResponseIden::Table) - .column(Asterisk) - .cond_where(Expr::col(HttpResponseIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) -} - -pub async fn delete_http_response( - app_handle: &AppHandle, - id: &str, - update_source: &UpdateSource, -) -> Result { - let resp = get_http_response(app_handle, id).await?; - - // Delete the body file if it exists - if let Some(p) = resp.body_path.clone() { - if let Err(e) = fs::remove_file(p) { - error!("Failed to delete body file: {}", e); - }; - } - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::delete() - .from_table(HttpResponseIden::Table) - .cond_where(Expr::col(HttpResponseIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params())?; - - emit_deleted_model(app_handle, &AnyModel::HttpResponse(resp.to_owned()), update_source); - Ok(resp) -} - -pub async fn delete_all_http_responses_for_request( - app_handle: &AppHandle, - request_id: &str, - update_source: &UpdateSource, -) -> Result<()> { - for r in list_http_responses_for_request(app_handle, request_id, None).await? { - delete_http_response(app_handle, &r.id, update_source).await?; - } - Ok(()) -} - -pub async fn delete_all_http_responses_for_workspace( - app_handle: &AppHandle, - workspace_id: &str, - update_source: &UpdateSource, -) -> Result<()> { - for r in list_http_responses_for_workspace(app_handle, workspace_id, None).await? { - delete_http_response(app_handle, &r.id, update_source).await?; - } - Ok(()) -} - -pub async fn list_http_responses_for_workspace( - app_handle: &AppHandle, - workspace_id: &str, - limit: Option, -) -> Result> { - let limit_unwrapped = limit.unwrap_or_else(|| i64::MAX); - let dbm = app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(HttpResponseIden::Table) - .cond_where(Expr::col(HttpResponseIden::WorkspaceId).eq(workspace_id)) - .column(Asterisk) - .order_by(HttpResponseIden::CreatedAt, Order::Desc) - .limit(limit_unwrapped as u64) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn list_http_responses_for_request( - app_handle: &AppHandle, - request_id: &str, - limit: Option, -) -> Result> { - let limit_unwrapped = limit.unwrap_or_else(|| i64::MAX); - let dbm = app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(HttpResponseIden::Table) - .cond_where(Expr::col(HttpResponseIden::RequestId).eq(request_id)) - .column(Asterisk) - .order_by(HttpResponseIden::CreatedAt, Order::Desc) - .limit(limit_unwrapped as u64) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn list_responses_by_workspace_id( - app_handle: &AppHandle, - workspace_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(HttpResponseIden::Table) - .cond_where(Expr::col(HttpResponseIden::WorkspaceId).eq(workspace_id)) - .column(Asterisk) - .order_by(HttpResponseIden::CreatedAt, Order::Desc) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn get_sync_state_for_model( - app_handle: &AppHandle, - workspace_id: &str, - model_id: &str, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(SyncStateIden::Table) - .column(Asterisk) - .cond_where( - Cond::all() - .add(Expr::col(SyncStateIden::ModelId).eq(model_id)) - .add(Expr::col(SyncStateIden::WorkspaceId).eq(workspace_id)), - ) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into()).optional()?) -} - -pub async fn list_sync_states_for_workspace( - app_handle: &AppHandle, - workspace_id: &str, - sync_dir: &Path, -) -> Result> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - let (sql, params) = Query::select() - .from(SyncStateIden::Table) - .column(Asterisk) - .cond_where( - Cond::all() - .add(Expr::col(SyncStateIden::WorkspaceId).eq(workspace_id)) - .add(Expr::col(SyncStateIden::SyncDir).eq(sync_dir.to_string_lossy())), - ) - .build_rusqlite(SqliteQueryBuilder); - let mut stmt = db.prepare(sql.as_str())?; - let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; - Ok(items.map(|v| v.unwrap()).collect()) -} - -pub async fn upsert_sync_state( - app_handle: &AppHandle, - sync_state: SyncState, -) -> Result { - let id = match sync_state.id.as_str() { - "" => generate_model_id(ModelType::TypeSyncState), - _ => sync_state.id.to_string(), - }; - - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::insert() - .into_table(SyncStateIden::Table) - .columns([ - SyncStateIden::Id, - SyncStateIden::WorkspaceId, - SyncStateIden::CreatedAt, - SyncStateIden::UpdatedAt, - SyncStateIden::FlushedAt, - SyncStateIden::Checksum, - SyncStateIden::ModelId, - SyncStateIden::RelPath, - SyncStateIden::SyncDir, - ]) - .values_panic([ - id.as_str().into(), - sync_state.workspace_id.into(), - CurrentTimestamp.into(), - CurrentTimestamp.into(), - sync_state.flushed_at.into(), - sync_state.checksum.into(), - sync_state.model_id.into(), - sync_state.rel_path.into(), - sync_state.sync_dir.into(), - ]) - .on_conflict( - OnConflict::columns(vec![SyncStateIden::WorkspaceId, SyncStateIden::ModelId]) - .update_columns([ - SyncStateIden::UpdatedAt, - SyncStateIden::FlushedAt, - SyncStateIden::Checksum, - SyncStateIden::RelPath, - SyncStateIden::SyncDir, - ]) - .to_owned(), - ) - .returning_all() - .build_rusqlite(SqliteQueryBuilder); - - let mut stmt = db.prepare(sql.as_str())?; - let m: SyncState = stmt.query_row(&*params.as_params(), |row| row.try_into())?; - Ok(m) -} - -pub async fn delete_sync_state(app_handle: &AppHandle, id: &str) -> Result<()> { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await.get().unwrap(); - - let (sql, params) = Query::delete() - .from_table(SyncStateIden::Table) - .cond_where(Expr::col(SyncStateIden::Id).eq(id)) - .build_rusqlite(SqliteQueryBuilder); - db.execute(sql.as_str(), &*params.as_params())?; - Ok(()) -} - -pub async fn debug_pool(app_handle: &AppHandle) { - let dbm = &*app_handle.state::(); - let db = dbm.0.lock().await; - debug!("Debug database state: {:?}", db.state()); -} - -pub fn generate_model_id(model: ModelType) -> String { - let id = generate_id(); - format!("{}_{}", model.id_prefix(), id) -} - -pub fn generate_id() -> String { - let alphabet: [char; 57] = [ - '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', - 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', - ]; - - nanoid!(10, &alphabet) -} - -#[derive(Debug, Clone, Serialize, Deserialize, TS)] -#[serde(rename_all = "camelCase")] -#[ts(export, export_to = "gen_models.ts")] -pub struct ModelPayload { - pub model: AnyModel, - pub update_source: UpdateSource, -} - -#[derive(Debug, Clone, Serialize, Deserialize, TS)] -#[serde(rename_all = "snake_case", tag = "type")] -#[ts(export, export_to = "gen_models.ts")] -pub enum UpdateSource { - Sync, - Window { label: String }, - Plugin, - Background, - Import, -} - -impl UpdateSource { - pub fn from_window(window: &WebviewWindow) -> Self { - Self::Window { - label: window.label().to_string(), - } - } -} - -fn emit_upserted_model( - app_handle: &AppHandle, - model: &AnyModel, - update_source: &UpdateSource, -) { - let payload = ModelPayload { - model: model.to_owned(), - update_source: update_source.to_owned(), - }; - - app_handle.emit("upserted_model", payload).unwrap(); -} - -fn emit_deleted_model( - app_handle: &AppHandle, - model: &AnyModel, - update_source: &UpdateSource, -) { - let payload = ModelPayload { - model: model.to_owned(), - update_source: update_source.to_owned(), - }; - app_handle.emit("deleted_model", payload).unwrap(); -} - -pub fn listen_to_model_delete(app_handle: &AppHandle, handler: F) -where - F: Fn(ModelPayload) + Send + 'static, - R: Runtime, -{ - app_handle.listen_any("deleted_model", move |e| { - match serde_json::from_str(e.payload()) { - Ok(payload) => handler(payload), - Err(e) => { - warn!("Failed to deserialize deleted model {}", e); - return; - } - }; - }); -} - -pub fn listen_to_model_upsert(app_handle: &AppHandle, handler: F) -where - F: Fn(ModelPayload) + Send + 'static, - R: Runtime, -{ - app_handle.listen_any("upserted_model", move |e| { - match serde_json::from_str(e.payload()) { - Ok(payload) => handler(payload), - Err(e) => { - warn!("Failed to deserialize upserted model {}", e); - return; - } - }; - }); -} - -#[derive(Default, Debug, Deserialize, Serialize)] -#[serde(default, rename_all = "camelCase")] -pub struct WorkspaceExport { - pub yaak_version: String, - pub yaak_schema: i64, - pub timestamp: NaiveDateTime, - pub resources: BatchUpsertResult, -} - -#[derive(Default, Debug, Deserialize, Serialize)] -#[serde(default, rename_all = "camelCase")] -pub struct BatchUpsertResult { - pub workspaces: Vec, - pub environments: Vec, - pub folders: Vec, - pub http_requests: Vec, - pub grpc_requests: Vec, - pub websocket_requests: Vec, -} - -pub async fn batch_upsert( - app_handle: &AppHandle, - workspaces: Vec, - environments: Vec, - folders: Vec, - http_requests: Vec, - grpc_requests: Vec, - websocket_requests: Vec, - update_source: &UpdateSource, -) -> Result { - let mut imported_resources = BatchUpsertResult::default(); - - if workspaces.len() > 0 { - info!("Batch inserting {} workspaces", workspaces.len()); - for v in workspaces { - let x = upsert_workspace(&app_handle, v, update_source).await?; - imported_resources.workspaces.push(x.clone()); - } - } - - if environments.len() > 0 { - while imported_resources.environments.len() < environments.len() { - for v in environments.clone() { - if let Some(id) = v.environment_id.clone() { - let has_parent_to_import = environments.iter().find(|m| m.id == id).is_some(); - let imported_parent = - imported_resources.environments.iter().find(|m| m.id == id); - // If there's also a parent to upsert, wait for that one - if imported_parent.is_none() && has_parent_to_import { - continue; - } - } - if let Some(_) = imported_resources.environments.iter().find(|f| f.id == v.id) { - continue; - } - let x = upsert_environment(&app_handle, v, update_source).await?; - imported_resources.environments.push(x.clone()); - } - } - info!("Imported {} environments", imported_resources.environments.len()); - } - - if folders.len() > 0 { - while imported_resources.folders.len() < folders.len() { - for v in folders.clone() { - if let Some(id) = v.folder_id.clone() { - let has_parent_to_import = folders.iter().find(|m| m.id == id).is_some(); - let imported_parent = imported_resources.folders.iter().find(|m| m.id == id); - // If there's also a parent to upsert, wait for that one - if imported_parent.is_none() && has_parent_to_import { - continue; - } - } - if let Some(_) = imported_resources.folders.iter().find(|f| f.id == v.id) { - continue; - } - let x = upsert_folder(&app_handle, v, update_source).await?; - imported_resources.folders.push(x.clone()); - } - } - info!("Imported {} folders", imported_resources.folders.len()); - } - - if http_requests.len() > 0 { - for v in http_requests { - let x = upsert_http_request(&app_handle, v, update_source).await?; - imported_resources.http_requests.push(x.clone()); - } - info!("Imported {} http_requests", imported_resources.http_requests.len()); - } - - if grpc_requests.len() > 0 { - for v in grpc_requests { - let x = upsert_grpc_request(&app_handle, v, update_source).await?; - imported_resources.grpc_requests.push(x.clone()); - } - info!("Imported {} grpc_requests", imported_resources.grpc_requests.len()); - } - - if websocket_requests.len() > 0 { - for v in websocket_requests { - let x = upsert_websocket_request(&app_handle, v, update_source).await?; - imported_resources.websocket_requests.push(x.clone()); - } - info!("Imported {} websocket_requests", imported_resources.websocket_requests.len()); - } - - Ok(imported_resources) -} - -pub async fn get_workspace_export_resources( - app_handle: &AppHandle, - workspace_ids: Vec<&str>, - include_environments: bool, -) -> Result { - let mut data = WorkspaceExport { - yaak_version: app_handle.package_info().version.clone().to_string(), - yaak_schema: 3, - timestamp: Utc::now().naive_utc(), - resources: BatchUpsertResult { - workspaces: Vec::new(), - environments: Vec::new(), - folders: Vec::new(), - http_requests: Vec::new(), - grpc_requests: Vec::new(), - websocket_requests: Vec::new(), - }, - }; - - for workspace_id in workspace_ids { - data.resources.workspaces.push(get_workspace(app_handle, workspace_id).await?); - data.resources.environments.append(&mut list_environments(app_handle, workspace_id).await?); - data.resources.folders.append(&mut list_folders(app_handle, workspace_id).await?); - data.resources - .http_requests - .append(&mut list_http_requests(app_handle, workspace_id).await?); - data.resources - .grpc_requests - .append(&mut list_grpc_requests(app_handle, workspace_id).await?); - data.resources - .websocket_requests - .append(&mut list_websocket_requests(app_handle, workspace_id).await?); - } - - // Nuke environments if we don't want them - if !include_environments { - data.resources.environments.clear(); - } - - Ok(data) -} - -// Generate the created_at or updated_at timestamps for an upsert operation, depending on the ID -// provided. -fn timestamp_for_upsert(update_source: &UpdateSource, dt: NaiveDateTime) -> NaiveDateTime { - match update_source { - // Sync and import operations always preserve timestamps - UpdateSource::Sync | UpdateSource::Import => { - if dt.and_utc().timestamp() == 0 { - // Sometimes data won't have timestamps (partial data) - Utc::now().naive_utc() - } else { - dt - } - } - // Other sources will always update to the latest time - _ => Utc::now().naive_utc(), - } -} diff --git a/src-tauri/yaak-models/src/queries/base.rs b/src-tauri/yaak-models/src/queries/base.rs new file mode 100644 index 000000000..c6df8ae72 --- /dev/null +++ b/src-tauri/yaak-models/src/queries/base.rs @@ -0,0 +1,169 @@ +use crate::error::Error::RowNotFound; +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{AnyModel, ModelType, UpsertModelInfo}; +use crate::queries_legacy::{generate_model_id, ModelChangeEvent, ModelPayload, UpdateSource}; +use rusqlite::OptionalExtension; +use sea_query::{ + Asterisk, Expr, IntoColumnRef, IntoIden, IntoTableRef, OnConflict, Query, SimpleExpr, + SqliteQueryBuilder, +}; +use sea_query_rusqlite::RusqliteBinder; + +pub(crate) const MAX_HISTORY_ITEMS: usize = 20; + +impl<'a> DbContext<'a> { + pub(crate) fn find_one<'s, M>( + &self, + col: impl IntoColumnRef, + value: impl Into, + ) -> Result + where + M: Into + Clone + UpsertModelInfo, + { + match self.find_optional::(col, value) { + Ok(Some(v)) => Ok(v), + Ok(None) => Err(RowNotFound), + Err(e) => Err(e), + } + } + + pub fn find_optional<'s, M>( + &self, + col: impl IntoColumnRef, + value: impl Into, + ) -> Result> + where + M: Into + Clone + UpsertModelInfo, + { + let (sql, params) = Query::select() + .from(M::table_name()) + .column(Asterisk) + .cond_where(Expr::col(col).eq(value)) + .build_rusqlite(SqliteQueryBuilder); + let mut stmt = self.conn.prepare(sql.as_str())?; + Ok(stmt.query_row(&*params.as_params(), M::from_row).optional()?) + } + + pub fn find_all<'s, M>(&self) -> Result> + where + M: Into + Clone + UpsertModelInfo, + { + let (sql, params) = Query::select() + .from(M::table_name()) + .column(Asterisk) + .build_rusqlite(SqliteQueryBuilder); + let mut stmt = self.conn.resolve().prepare(sql.as_str())?; + let items = stmt.query_map(&*params.as_params(), M::from_row)?; + Ok(items.map(|v| v.unwrap()).collect()) + } + + pub fn find_many<'s, M>( + &self, + col: impl IntoColumnRef, + value: impl Into, + limit: Option, + ) -> Result> + where + M: Into + Clone + UpsertModelInfo, + { + // TODO: Figure out how to do this conditional builder better + let (sql, params) = if let Some(limit) = limit { + Query::select() + .from(M::table_name()) + .column(Asterisk) + .cond_where(Expr::col(col).eq(value)) + .limit(limit) + .build_rusqlite(SqliteQueryBuilder) + } else { + Query::select() + .from(M::table_name()) + .column(Asterisk) + .cond_where(Expr::col(col).eq(value)) + .build_rusqlite(SqliteQueryBuilder) + }; + + let mut stmt = self.conn.resolve().prepare(sql.as_str())?; + let items = stmt.query_map(&*params.as_params(), M::from_row)?; + Ok(items.map(|v| v.unwrap()).collect()) + } + + pub fn upsert(&self, model: &M, source: &UpdateSource) -> Result + where + M: Into + From + UpsertModelInfo + Clone, + { + self.upsert_one( + M::table_name(), + M::id_column(), + model.get_id().as_str(), + || generate_model_id(ModelType::TypeEnvironment), + model.clone().insert_values(source)?, + M::update_columns(), + source, + ) + } + + fn upsert_one( + &self, + table: impl IntoTableRef, + id_col: impl IntoIden + Eq + Clone, + id_val: &str, + gen_id: fn() -> String, + other_values: Vec<(impl IntoIden + Eq, impl Into)>, + update_columns: Vec, + source: &UpdateSource, + ) -> Result + where + M: Into + From + UpsertModelInfo + Clone, + { + let id_iden = id_col.into_iden(); + let mut column_vec = vec![id_iden.clone()]; + let mut value_vec = vec![if id_val == "" { gen_id().into() } else { id_val.into() }]; + + for (col, val) in other_values { + value_vec.push(val.into()); + column_vec.push(col.into_iden()); + } + + let on_conflict = OnConflict::column(id_iden).update_columns(update_columns).to_owned(); + let (sql, params) = Query::insert() + .into_table(table) + .columns(column_vec) + .values_panic(value_vec) + .on_conflict(on_conflict) + .returning_all() + .build_rusqlite(SqliteQueryBuilder); + + let mut stmt = self.conn.resolve().prepare(sql.as_str())?; + let m: M = stmt.query_row(&*params.as_params(), |row| M::from_row(row))?; + + let payload = ModelPayload { + model: m.clone().into(), + update_source: source.clone(), + change: ModelChangeEvent::Upsert, + }; + self.tx.try_send(payload).unwrap(); + + Ok(m) + } + + pub(crate) fn delete<'s, M>(&self, m: &M, update_source: &UpdateSource) -> Result + where + M: Into + Clone + UpsertModelInfo, + { + let (sql, params) = Query::delete() + .from_table(M::table_name()) + .cond_where(Expr::col(M::id_column().into_iden()).eq(m.get_id())) + .build_rusqlite(SqliteQueryBuilder); + self.conn.execute(sql.as_str(), &*params.as_params())?; + + let payload = ModelPayload { + model: m.clone().into(), + update_source: update_source.clone(), + change: ModelChangeEvent::Delete, + }; + + self.tx.try_send(payload).unwrap(); + Ok(m.clone()) + } +} diff --git a/src-tauri/yaak-models/src/queries/batch.rs b/src-tauri/yaak-models/src/queries/batch.rs new file mode 100644 index 000000000..92135b8fd --- /dev/null +++ b/src-tauri/yaak-models/src/queries/batch.rs @@ -0,0 +1,99 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{Environment, Folder, GrpcRequest, HttpRequest, WebsocketRequest, Workspace}; +use crate::queries_legacy::{BatchUpsertResult, UpdateSource}; +use log::info; + +impl<'a> DbContext<'a> { + pub fn batch_upsert( + &self, + workspaces: Vec, + environments: Vec, + folders: Vec, + http_requests: Vec, + grpc_requests: Vec, + websocket_requests: Vec, + source: &UpdateSource, + ) -> Result { + let mut imported_resources = BatchUpsertResult::default(); + + if workspaces.len() > 0 { + info!("Batch inserting {} workspaces", workspaces.len()); + for v in workspaces { + let x = self.upsert_workspace(&v, source)?; + imported_resources.workspaces.push(x.clone()); + } + } + + if environments.len() > 0 { + while imported_resources.environments.len() < environments.len() { + for v in environments.clone() { + if let Some(id) = v.environment_id.clone() { + let has_parent_to_import = + environments.iter().find(|m| m.id == id).is_some(); + let imported_parent = + imported_resources.environments.iter().find(|m| m.id == id); + // If there's also a parent to upsert, wait for that one + if imported_parent.is_none() && has_parent_to_import { + continue; + } + } + if let Some(_) = imported_resources.environments.iter().find(|f| f.id == v.id) { + continue; + } + let x = self.upsert_environment(&v, source)?; + imported_resources.environments.push(x.clone()); + } + } + info!("Imported {} environments", imported_resources.environments.len()); + } + + if folders.len() > 0 { + while imported_resources.folders.len() < folders.len() { + for v in folders.clone() { + if let Some(id) = v.folder_id.clone() { + let has_parent_to_import = folders.iter().find(|m| m.id == id).is_some(); + let imported_parent = + imported_resources.folders.iter().find(|m| m.id == id); + // If there's also a parent to upsert, wait for that one + if imported_parent.is_none() && has_parent_to_import { + continue; + } + } + if let Some(_) = imported_resources.folders.iter().find(|f| f.id == v.id) { + continue; + } + let x = self.upsert_folder(&v, source)?; + imported_resources.folders.push(x.clone()); + } + } + info!("Imported {} folders", imported_resources.folders.len()); + } + + if http_requests.len() > 0 { + for v in http_requests { + let x = self.upsert(&v, source)?; + imported_resources.http_requests.push(x.clone()); + } + info!("Imported {} http_requests", imported_resources.http_requests.len()); + } + + if grpc_requests.len() > 0 { + for v in grpc_requests { + let x = self.upsert_grpc_request(&v, source)?; + imported_resources.grpc_requests.push(x.clone()); + } + info!("Imported {} grpc_requests", imported_resources.grpc_requests.len()); + } + + if websocket_requests.len() > 0 { + for v in websocket_requests { + let x = self.upsert_websocket_request(&v, source)?; + imported_resources.websocket_requests.push(x.clone()); + } + info!("Imported {} websocket_requests", imported_resources.websocket_requests.len()); + } + + Ok(imported_resources) + } +} diff --git a/src-tauri/yaak-models/src/queries/cookie_jars.rs b/src-tauri/yaak-models/src/queries/cookie_jars.rs new file mode 100644 index 000000000..aefdf7c3a --- /dev/null +++ b/src-tauri/yaak-models/src/queries/cookie_jars.rs @@ -0,0 +1,35 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{CookieJar, CookieJarIden}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_cookie_jar(&self, id: &str) -> Result { + self.find_one(CookieJarIden::Id, id) + } + + pub fn list_cookie_jars(&self, workspace_id: &str) -> Result> { + self.find_many(CookieJarIden::WorkspaceId, workspace_id, None) + } + + pub fn delete_cookie_jar( + &self, + cookie_jar: &CookieJar, + source: &UpdateSource, + ) -> Result { + self.delete(cookie_jar, source) + } + + pub fn delete_cookie_jar_by_id(&self, id: &str, source: &UpdateSource) -> Result { + let cookie_jar = self.get_cookie_jar(id)?; + self.delete_cookie_jar(&cookie_jar, source) + } + + pub fn upsert_cookie_jar( + &self, + cookie_jar: &CookieJar, + source: &UpdateSource, + ) -> Result { + self.upsert(cookie_jar, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/environments.rs b/src-tauri/yaak-models/src/queries/environments.rs new file mode 100644 index 000000000..8a8baf06a --- /dev/null +++ b/src-tauri/yaak-models/src/queries/environments.rs @@ -0,0 +1,79 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{Environment, EnvironmentIden, UpsertModelInfo}; +use crate::queries_legacy::UpdateSource; +use log::info; +use sea_query::ColumnRef::Asterisk; +use sea_query::{Cond, Expr, Query, SqliteQueryBuilder}; +use sea_query_rusqlite::RusqliteBinder; + +impl<'a> DbContext<'a> { + pub fn get_environment(&self, id: &str) -> Result { + self.find_one(EnvironmentIden::Id, id) + } + + pub fn get_base_environment(&self, workspace_id: &str) -> Result { + let (sql, params) = Query::select() + .from(EnvironmentIden::Table) + .column(Asterisk) + .cond_where( + Cond::all() + .add(Expr::col(EnvironmentIden::WorkspaceId).eq(workspace_id)) + .add(Expr::col(EnvironmentIden::EnvironmentId).is_null()), + ) + .build_rusqlite(SqliteQueryBuilder); + let mut stmt = self.conn.prepare(sql.as_str())?; + Ok(stmt.query_row(&*params.as_params(), Environment::from_row)?) + } + + pub fn ensure_base_environment(&self, workspace_id: &str) -> Result<()> { + let environments = self.list_environments(workspace_id)?; + let base_environment = environments + .iter() + .find(|e| e.environment_id == None && e.workspace_id == workspace_id); + + if let None = base_environment { + info!("Creating base environment for {workspace_id}"); + self.upsert_environment( + &Environment { + workspace_id: workspace_id.to_string(), + name: "Global Variables".to_string(), + ..Default::default() + }, + &UpdateSource::Background, + )?; + } + + Ok(()) + } + + pub fn list_environments(&self, workspace_id: &str) -> Result> { + self.find_many(EnvironmentIden::WorkspaceId, workspace_id, None) + } + + pub fn delete_environment( + &self, + environment: &Environment, + source: &UpdateSource, + ) -> Result { + for environment in + self.find_many::(EnvironmentIden::EnvironmentId, &environment.id, None)? + { + self.delete_environment(&environment, source)?; + } + self.delete(environment, source) + } + + pub fn delete_environment_by_id(&self, id: &str, source: &UpdateSource) -> Result { + let environment = self.get_environment(id)?; + self.delete_environment(&environment, source) + } + + pub fn upsert_environment( + &self, + environment: &Environment, + source: &UpdateSource, + ) -> Result { + self.upsert(environment, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/folders.rs b/src-tauri/yaak-models/src/queries/folders.rs new file mode 100644 index 000000000..156b73387 --- /dev/null +++ b/src-tauri/yaak-models/src/queries/folders.rs @@ -0,0 +1,106 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{ + Folder, FolderIden, GrpcRequest, GrpcRequestIden, HttpRequest, HttpRequestIden, + WebsocketRequest, WebsocketRequestIden, +}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_folder(&self, id: &str) -> Result { + self.find_one(FolderIden::Id, id) + } + + pub fn list_folders(&self, workspace_id: &str) -> Result> { + self.find_many(FolderIden::WorkspaceId, workspace_id, None) + } + + pub fn delete_folder(&self, folder: &Folder, source: &UpdateSource) -> Result { + for folder in self.find_many::(FolderIden::FolderId, &folder.id, None)? { + self.delete_folder(&folder, source)?; + } + for request in self.find_many::(HttpRequestIden::FolderId, &folder.id, None)? { + self.delete_http_request(&request, source)?; + } + for request in self.find_many::(GrpcRequestIden::FolderId, &folder.id, None)? { + self.delete_grpc_request(&request, source)?; + } + for request in + self.find_many::(WebsocketRequestIden::FolderId, &folder.id, None)? + { + self.delete_websocket_request(&request, source)?; + } + self.delete(folder, source) + } + + pub fn delete_folder_by_id(&self, id: &str, source: &UpdateSource) -> Result { + let folder = self.get_folder(id)?; + self.delete_folder(&folder, source) + } + + pub fn upsert_folder(&self, folder: &Folder, source: &UpdateSource) -> Result { + self.upsert(folder, source) + } + + pub fn duplicate_folder(&self, src_folder: &Folder, source: &UpdateSource) -> Result { + let workspace_id = src_folder.workspace_id.as_str(); + + let http_requests = self + .find_many::(HttpRequestIden::WorkspaceId, workspace_id, None)? + .into_iter() + .filter(|m| m.folder_id.as_ref() == Some(&src_folder.id)); + + let grpc_requests = self + .find_many::(GrpcRequestIden::WorkspaceId, workspace_id, None)? + .into_iter() + .filter(|m| m.folder_id.as_ref() == Some(&src_folder.id)); + + let folders = self + .find_many::(FolderIden::WorkspaceId, workspace_id, None)? + .into_iter() + .filter(|m| m.folder_id.as_ref() == Some(&src_folder.id)); + + let new_folder = self.upsert_folder( + &Folder { + id: "".into(), + sort_priority: src_folder.sort_priority + 0.001, + ..src_folder.clone() + }, + source, + )?; + + for m in http_requests { + self.upsert_http_request( + &HttpRequest { + id: "".into(), + folder_id: Some(new_folder.id.clone()), + sort_priority: m.sort_priority + 0.001, + ..m + }, + source, + )?; + } + for m in grpc_requests { + self.upsert_grpc_request( + &GrpcRequest { + id: "".into(), + folder_id: Some(new_folder.id.clone()), + sort_priority: m.sort_priority + 0.001, + ..m + }, + source, + )?; + } + for m in folders { + // Recurse down + self.duplicate_folder( + &Folder { + folder_id: Some(new_folder.id.clone()), + ..m + }, + source, + )?; + } + Ok(new_folder) + } +} diff --git a/src-tauri/yaak-models/src/queries/grpc_connections.rs b/src-tauri/yaak-models/src/queries/grpc_connections.rs new file mode 100644 index 000000000..4d442853c --- /dev/null +++ b/src-tauri/yaak-models/src/queries/grpc_connections.rs @@ -0,0 +1,98 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{GrpcConnection, GrpcConnectionIden, GrpcConnectionState}; +use crate::queries::base::MAX_HISTORY_ITEMS; +use crate::queries_legacy::UpdateSource; +use log::debug; +use sea_query::{Expr, Query, SqliteQueryBuilder}; +use sea_query_rusqlite::RusqliteBinder; + +impl<'a> DbContext<'a> { + pub fn get_grpc_connection(&self, id: &str) -> Result { + self.find_one(GrpcConnectionIden::Id, id) + } + + pub fn delete_all_grpc_connections_for_request( + &self, + request_id: &str, + source: &UpdateSource, + ) -> Result<()> { + let responses = self.list_grpc_connections_for_request(request_id, None)?; + for m in responses { + self.delete(&m, source)?; + } + Ok(()) + } + + pub fn delete_all_grpc_connections_for_workspace( + &self, + workspace_id: &str, + source: &UpdateSource, + ) -> Result<()> { + for m in self.list_grpc_connections_for_workspace(workspace_id, None)? { + self.delete(&m, source)?; + } + Ok(()) + } + + pub fn delete_grpc_connection( + &self, + m: &GrpcConnection, + source: &UpdateSource, + ) -> Result { + self.delete(m, source) + } + + pub fn delete_grpc_connection_by_id( + &self, + id: &str, + source: &UpdateSource, + ) -> Result { + let grpc_connection = self.get_grpc_connection(id)?; + self.delete_grpc_connection(&grpc_connection, source) + } + + pub fn list_grpc_connections_for_request( + &self, + request_id: &str, + limit: Option, + ) -> Result> { + self.find_many(GrpcConnectionIden::RequestId, request_id, limit) + } + + pub fn list_grpc_connections_for_workspace( + &self, + workspace_id: &str, + limit: Option, + ) -> Result> { + self.find_many(GrpcConnectionIden::WorkspaceId, workspace_id, limit) + } + + pub fn cancel_pending_grpc_connections(&self) -> Result<()> { + let closed = serde_json::to_value(&GrpcConnectionState::Closed)?; + let (sql, params) = Query::update() + .table(GrpcConnectionIden::Table) + .values([(GrpcConnectionIden::State, closed.as_str().into())]) + .cond_where(Expr::col(GrpcConnectionIden::State).ne(closed.as_str())) + .build_rusqlite(SqliteQueryBuilder); + let mut stmt = self.conn.prepare(sql.as_str())?; + stmt.execute(&*params.as_params())?; + Ok(()) + } + + pub fn upsert_grpc_connection( + &self, + grpc_connection: &GrpcConnection, + source: &UpdateSource, + ) -> Result { + let connections = + self.list_grpc_connections_for_request(grpc_connection.request_id.as_str(), None)?; + + for m in connections.iter().skip(MAX_HISTORY_ITEMS - 1) { + debug!("Deleting old gRPC connection {}", grpc_connection.id); + self.delete_grpc_connection(&m, source)?; + } + + self.upsert(grpc_connection, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/grpc_events.rs b/src-tauri/yaak-models/src/queries/grpc_events.rs new file mode 100644 index 000000000..4b68ba4f7 --- /dev/null +++ b/src-tauri/yaak-models/src/queries/grpc_events.rs @@ -0,0 +1,22 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{GrpcEvent, GrpcEventIden}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_grpc_events(&self, id: &str) -> Result { + self.find_one(GrpcEventIden::Id, id) + } + + pub fn list_grpc_events(&self, connection_id: &str) -> Result> { + self.find_many(GrpcEventIden::ConnectionId, connection_id, None) + } + + pub fn upsert_grpc_event( + &self, + grpc_event: &GrpcEvent, + source: &UpdateSource, + ) -> Result { + self.upsert(grpc_event, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/grpc_requests.rs b/src-tauri/yaak-models/src/queries/grpc_requests.rs new file mode 100644 index 000000000..377ca25ea --- /dev/null +++ b/src-tauri/yaak-models/src/queries/grpc_requests.rs @@ -0,0 +1,51 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{GrpcRequest, GrpcRequestIden}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_grpc_request(&self, id: &str) -> Result> { + self.find_optional(GrpcRequestIden::Id, id) + } + + pub fn list_grpc_requests(&self, workspace_id: &str) -> Result> { + self.find_many(GrpcRequestIden::WorkspaceId, workspace_id, None) + } + + pub fn delete_grpc_request( + &self, + m: &GrpcRequest, + source: &UpdateSource, + ) -> Result { + self.delete_all_grpc_connections_for_request(m.id.as_str(), source)?; + self.delete(m, source) + } + + pub fn delete_grpc_request_by_id( + &self, + id: &str, + source: &UpdateSource, + ) -> Result { + let request = self.get_grpc_request(id)?.unwrap(); + self.delete_grpc_request(&request, source) + } + + pub fn duplicate_grpc_request( + &self, + grpc_request: &GrpcRequest, + source: &UpdateSource, + ) -> Result { + let mut request = grpc_request.clone(); + request.id = "".to_string(); + request.sort_priority = request.sort_priority + 0.001; + self.upsert(&request, source) + } + + pub fn upsert_grpc_request( + &self, + grpc_request: &GrpcRequest, + source: &UpdateSource, + ) -> Result { + self.upsert(grpc_request, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/http_requests.rs b/src-tauri/yaak-models/src/queries/http_requests.rs new file mode 100644 index 000000000..95c7c2004 --- /dev/null +++ b/src-tauri/yaak-models/src/queries/http_requests.rs @@ -0,0 +1,51 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{HttpRequest, HttpRequestIden}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_http_request(&self, id: &str) -> Result> { + self.find_optional(HttpRequestIden::Id, id) + } + + pub fn list_http_requests(&self, workspace_id: &str) -> Result> { + self.find_many(HttpRequestIden::WorkspaceId, workspace_id, None) + } + + pub fn delete_http_request( + &self, + m: &HttpRequest, + source: &UpdateSource, + ) -> Result { + self.delete_all_http_responses_for_request(m.id.as_str(), source)?; + self.delete(m, source) + } + + pub fn delete_http_request_by_id( + &self, + id: &str, + source: &UpdateSource, + ) -> Result { + let http_request = self.get_http_request(id)?.unwrap(); + self.delete_http_request(&http_request, source) + } + + pub fn duplicate_http_request( + &self, + http_request: &HttpRequest, + source: &UpdateSource, + ) -> Result { + let mut http_request = http_request.clone(); + http_request.id = "".to_string(); + http_request.sort_priority = http_request.sort_priority + 0.001; + self.upsert(&http_request, source) + } + + pub fn upsert_http_request( + &self, + http_request: &HttpRequest, + source: &UpdateSource, + ) -> Result { + self.upsert(http_request, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/http_responses.rs b/src-tauri/yaak-models/src/queries/http_responses.rs new file mode 100644 index 000000000..860a9707a --- /dev/null +++ b/src-tauri/yaak-models/src/queries/http_responses.rs @@ -0,0 +1,110 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{HttpResponse, HttpResponseIden, HttpResponseState}; +use crate::queries::base::MAX_HISTORY_ITEMS; +use crate::queries_legacy::UpdateSource; +use log::{debug, error}; +use sea_query::{Expr, Query, SqliteQueryBuilder}; +use sea_query_rusqlite::RusqliteBinder; +use std::fs; + +impl<'a> DbContext<'a> { + pub fn get_http_response(&self, id: &str) -> Result { + self.find_one(HttpResponseIden::Id, id) + } + + pub fn list_http_responses_for_request( + &self, + request_id: &str, + limit: Option, + ) -> Result> { + self.find_many(HttpResponseIden::RequestId, request_id, limit) + } + + pub fn list_http_responses_for_workspace( + &self, + workspace_id: &str, + limit: Option, + ) -> Result> { + self.find_many(HttpResponseIden::WorkspaceId, workspace_id, limit) + } + + pub fn delete_all_http_responses_for_request( + &self, + request_id: &str, + source: &UpdateSource, + ) -> Result<()> { + let responses = self.list_http_responses_for_request(request_id, None)?; + for m in responses { + self.delete(&m, source)?; + } + Ok(()) + } + + pub fn delete_all_http_responses_for_workspace( + &self, + workspace_id: &str, + source: &UpdateSource, + ) -> Result<()> { + let responses = + self.find_many::(HttpResponseIden::WorkspaceId, workspace_id, None)?; + for m in responses { + self.delete(&m, source)?; + } + Ok(()) + } + + pub fn delete_http_response( + &self, + http_response: &HttpResponse, + source: &UpdateSource, + ) -> Result { + // Delete the body file if it exists + if let Some(p) = http_response.body_path.clone() { + if let Err(e) = fs::remove_file(p) { + error!("Failed to delete body file: {}", e); + }; + } + + Ok(self.delete(http_response, source)?) + } + + pub fn upsert_http_response( + &self, + http_response: &HttpResponse, + source: &UpdateSource, + ) -> Result { + let responses = self.list_http_responses_for_request(&http_response.request_id, None)?; + + for m in responses.iter().skip(MAX_HISTORY_ITEMS - 1) { + debug!("Deleting old HTTP response {}", http_response.id); + self.delete_http_response(&m, source)?; + } + + self.upsert(http_response, source) + } + + pub fn cancel_pending_http_responses(&self) -> Result<()> { + let closed = serde_json::to_value(&HttpResponseState::Closed)?; + let (sql, params) = Query::update() + .table(HttpResponseIden::Table) + .values([(HttpResponseIden::State, closed.as_str().into())]) + .cond_where(Expr::col(HttpResponseIden::State).ne(closed.as_str())) + .build_rusqlite(SqliteQueryBuilder); + let mut stmt = self.conn.prepare(sql.as_str())?; + stmt.execute(&*params.as_params())?; + Ok(()) + } + + pub fn update_http_response_if_id( + &self, + response: &HttpResponse, + source: &UpdateSource, + ) -> Result { + if response.id.is_empty() { + Ok(response.clone()) + } else { + self.upsert(response, source) + } + } +} diff --git a/src-tauri/yaak-models/src/queries/key_values.rs b/src-tauri/yaak-models/src/queries/key_values.rs new file mode 100644 index 000000000..f601a4a1a --- /dev/null +++ b/src-tauri/yaak-models/src/queries/key_values.rs @@ -0,0 +1,164 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{KeyValue, KeyValueIden}; +use crate::queries_legacy::{ModelChangeEvent, ModelPayload, UpdateSource}; +use log::error; +use sea_query::Keyword::CurrentTimestamp; +use sea_query::{Asterisk, Cond, Expr, OnConflict, Query, SqliteQueryBuilder}; +use sea_query_rusqlite::RusqliteBinder; + +impl<'a> DbContext<'a> { + pub fn list_key_values_raw(&self) -> Result> { + let (sql, params) = Query::select() + .from(KeyValueIden::Table) + .column(Asterisk) + .build_rusqlite(SqliteQueryBuilder); + let mut stmt = self.conn.prepare(sql.as_str())?; + let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?; + Ok(items.map(|v| v.unwrap()).collect()) + } + + pub fn get_key_value_string(&self, namespace: &str, key: &str, default: &str) -> String { + match self.get_key_value_raw(namespace, key) { + None => default.to_string(), + Some(v) => { + let result = serde_json::from_str(&v.value); + match result { + Ok(v) => v, + Err(e) => { + error!("Failed to parse string key value: {}", e); + default.to_string() + } + } + } + } + } + + pub fn get_key_value_int(&self, namespace: &str, key: &str, default: i32) -> i32 { + match self.get_key_value_raw(namespace, key) { + None => default.clone(), + Some(v) => { + let result = serde_json::from_str(&v.value); + match result { + Ok(v) => v, + Err(e) => { + error!("Failed to parse int key value: {}", e); + default.clone() + } + } + } + } + } + + pub fn get_key_value_raw(&self, namespace: &str, key: &str) -> Option { + let (sql, params) = Query::select() + .from(KeyValueIden::Table) + .column(Asterisk) + .cond_where( + Cond::all() + .add(Expr::col(KeyValueIden::Namespace).eq(namespace)) + .add(Expr::col(KeyValueIden::Key).eq(key)), + ) + .build_rusqlite(SqliteQueryBuilder); + self.conn.resolve().query_row(sql.as_str(), &*params.as_params(), |row| row.try_into()).ok() + } + + pub fn set_key_value_string( + &self, + namespace: &str, + key: &str, + value: &str, + source: &UpdateSource, + ) -> (KeyValue, bool) { + let encoded = serde_json::to_string(&value).unwrap(); + self.set_key_value_raw(namespace, key, &encoded, source) + } + + pub fn set_key_value_int( + &self, + namespace: &str, + key: &str, + value: i32, + source: &UpdateSource, + ) -> (KeyValue, bool) { + let encoded = serde_json::to_string(&value).unwrap(); + self.set_key_value_raw(namespace, key, &encoded, source) + } + + pub fn set_key_value_raw( + &self, + namespace: &str, + key: &str, + value: &str, + source: &UpdateSource, + ) -> (KeyValue, bool) { + let existing = self.get_key_value_raw(namespace, key); + + let (sql, params) = Query::insert() + .into_table(KeyValueIden::Table) + .columns([ + KeyValueIden::CreatedAt, + KeyValueIden::UpdatedAt, + KeyValueIden::Namespace, + KeyValueIden::Key, + KeyValueIden::Value, + ]) + .values_panic([ + CurrentTimestamp.into(), + CurrentTimestamp.into(), + namespace.into(), + key.into(), + value.into(), + ]) + .on_conflict( + OnConflict::new() + .update_columns([KeyValueIden::UpdatedAt, KeyValueIden::Value]) + .to_owned(), + ) + .returning_all() + .build_rusqlite(SqliteQueryBuilder); + + let mut stmt = self.conn.prepare(sql.as_str()).expect("Failed to prepare KeyValue upsert"); + let m: KeyValue = stmt + .query_row(&*params.as_params(), |row| row.try_into()) + .expect("Failed to upsert KeyValue"); + + let payload = ModelPayload { + model: m.clone().into(), + update_source: source.clone(), + change: ModelChangeEvent::Upsert, + }; + self.tx.try_send(payload).unwrap(); + + (m, existing.is_none()) + } + + pub fn delete_key_value( + &self, + namespace: &str, + key: &str, + source: &UpdateSource, + ) -> Result<()> { + let kv = match self.get_key_value_raw(namespace, key) { + None => return Ok(()), + Some(m) => m, + }; + + let (sql, params) = Query::delete() + .from_table(KeyValueIden::Table) + .cond_where( + Cond::all() + .add(Expr::col(KeyValueIden::Namespace).eq(namespace)) + .add(Expr::col(KeyValueIden::Key).eq(key)), + ) + .build_rusqlite(SqliteQueryBuilder); + self.conn.execute(sql.as_str(), &*params.as_params())?; + let payload = ModelPayload { + model: kv.clone().into(), + update_source: source.clone(), + change: ModelChangeEvent::Delete, + }; + self.tx.try_send(payload).unwrap(); + Ok(()) + } +} diff --git a/src-tauri/yaak-models/src/queries/mod.rs b/src-tauri/yaak-models/src/queries/mod.rs new file mode 100644 index 000000000..a86d1e18c --- /dev/null +++ b/src-tauri/yaak-models/src/queries/mod.rs @@ -0,0 +1,20 @@ +mod base; +mod batch; +mod cookie_jars; +mod environments; +mod folders; +mod grpc_connections; +mod grpc_events; +mod grpc_requests; +mod http_requests; +mod http_responses; +mod key_values; +mod plugin_key_values; +mod plugins; +mod settings; +mod sync_states; +mod websocket_connections; +mod websocket_events; +mod websocket_requests; +mod workspace_metas; +mod workspaces; diff --git a/src-tauri/yaak-models/src/queries/plugin_key_values.rs b/src-tauri/yaak-models/src/queries/plugin_key_values.rs new file mode 100644 index 000000000..37d8760d9 --- /dev/null +++ b/src-tauri/yaak-models/src/queries/plugin_key_values.rs @@ -0,0 +1,79 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{PluginKeyValue, PluginKeyValueIden}; +use sea_query::Keyword::CurrentTimestamp; +use sea_query::{Asterisk, Cond, Expr, OnConflict, Query, SqliteQueryBuilder}; +use sea_query_rusqlite::RusqliteBinder; + +impl<'a> DbContext<'a> { + pub fn get_plugin_key_value(&self, plugin_name: &str, key: &str) -> Option { + let (sql, params) = Query::select() + .from(PluginKeyValueIden::Table) + .column(Asterisk) + .cond_where( + Cond::all() + .add(Expr::col(PluginKeyValueIden::PluginName).eq(plugin_name)) + .add(Expr::col(PluginKeyValueIden::Key).eq(key)), + ) + .build_rusqlite(SqliteQueryBuilder); + self.conn.resolve().query_row(sql.as_str(), &*params.as_params(), |row| row.try_into()).ok() + } + + pub fn set_plugin_key_value( + &self, + plugin_name: &str, + key: &str, + value: &str, + ) -> (PluginKeyValue, bool) { + let existing = self.get_plugin_key_value(plugin_name, key); + + let (sql, params) = Query::insert() + .into_table(PluginKeyValueIden::Table) + .columns([ + PluginKeyValueIden::CreatedAt, + PluginKeyValueIden::UpdatedAt, + PluginKeyValueIden::PluginName, + PluginKeyValueIden::Key, + PluginKeyValueIden::Value, + ]) + .values_panic([ + CurrentTimestamp.into(), + CurrentTimestamp.into(), + plugin_name.into(), + key.into(), + value.into(), + ]) + .on_conflict( + OnConflict::new() + .update_columns([PluginKeyValueIden::UpdatedAt, PluginKeyValueIden::Value]) + .to_owned(), + ) + .returning_all() + .build_rusqlite(SqliteQueryBuilder); + + let mut stmt = + self.conn.prepare(sql.as_str()).expect("Failed to prepare PluginKeyValue upsert"); + let m: PluginKeyValue = stmt + .query_row(&*params.as_params(), |row| row.try_into()) + .expect("Failed to upsert KeyValue"); + + (m, existing.is_none()) + } + + pub fn delete_plugin_key_value(&self, namespace: &str, key: &str) -> Result { + if let None = self.get_plugin_key_value(namespace, key) { + return Ok(false); + }; + + let (sql, params) = Query::delete() + .from_table(PluginKeyValueIden::Table) + .cond_where( + Cond::all() + .add(Expr::col(PluginKeyValueIden::PluginName).eq(namespace)) + .add(Expr::col(PluginKeyValueIden::Key).eq(key)), + ) + .build_rusqlite(SqliteQueryBuilder); + self.conn.execute(sql.as_str(), &*params.as_params())?; + Ok(true) + } +} diff --git a/src-tauri/yaak-models/src/queries/plugins.rs b/src-tauri/yaak-models/src/queries/plugins.rs new file mode 100644 index 000000000..830c0f582 --- /dev/null +++ b/src-tauri/yaak-models/src/queries/plugins.rs @@ -0,0 +1,27 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{Plugin, PluginIden}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_plugin(&self, id: &str) -> Result { + self.find_one(PluginIden::Id, id) + } + + pub fn list_plugins(&self) -> Result> { + self.find_all() + } + + pub fn delete_plugin(&self, plugin: &Plugin, source: &UpdateSource) -> Result { + self.delete(plugin, source) + } + + pub fn delete_plugin_by_id(&self, id: &str, source: &UpdateSource) -> Result { + let plugin = self.get_plugin(id)?; + self.delete_plugin(&plugin, source) + } + + pub fn upsert_plugin(&self, plugin: &Plugin, source: &UpdateSource) -> Result { + self.upsert(plugin, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/settings.rs b/src-tauri/yaak-models/src/queries/settings.rs new file mode 100644 index 000000000..63d8f6cda --- /dev/null +++ b/src-tauri/yaak-models/src/queries/settings.rs @@ -0,0 +1,25 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{Settings, SettingsIden}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_or_create_settings(&self, source: &UpdateSource) -> Result { + let id = "default"; + if let Some(s) = self.find_optional::(SettingsIden::Id, id)? { + return Ok(s); + }; + + self.upsert( + &Settings { + id: id.to_string(), + ..Default::default() + }, + source, + ) + } + + pub fn upsert_settings(&self, settings: &Settings, source: &UpdateSource) -> Result { + self.upsert(settings, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/sync_states.rs b/src-tauri/yaak-models/src/queries/sync_states.rs new file mode 100644 index 000000000..fb84c5d3a --- /dev/null +++ b/src-tauri/yaak-models/src/queries/sync_states.rs @@ -0,0 +1,45 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{SyncState, SyncStateIden, UpsertModelInfo}; +use crate::queries_legacy::UpdateSource; +use sea_query::{Asterisk, Cond, Expr, Query, SqliteQueryBuilder}; +use sea_query_rusqlite::RusqliteBinder; +use std::path::Path; + +impl<'a> DbContext<'a> { + pub fn get_sync_state(&self, id: &str) -> Result { + self.find_one(SyncStateIden::Id, id) + } + + pub fn upsert_sync_state(&self, sync_state: &SyncState) -> Result { + self.upsert(sync_state, &UpdateSource::Sync) + } + + pub fn list_sync_states_for_workspace( + &self, + workspace_id: &str, + sync_dir: &Path, + ) -> Result> { + let (sql, params) = Query::select() + .from(SyncStateIden::Table) + .column(Asterisk) + .cond_where( + Cond::all() + .add(Expr::col(SyncStateIden::WorkspaceId).eq(workspace_id)) + .add(Expr::col(SyncStateIden::SyncDir).eq(sync_dir.to_string_lossy())), + ) + .build_rusqlite(SqliteQueryBuilder); + let mut stmt = self.conn.prepare(sql.as_str())?; + let items = stmt.query_map(&*params.as_params(), SyncState::from_row)?; + Ok(items.map(|v| v.unwrap()).collect()) + } + + pub fn delete_sync_state(&self, sync_state: &SyncState) -> Result { + self.delete(sync_state, &UpdateSource::Sync) + } + + pub fn delete_sync_state_by_id(&self, id: &str) -> Result { + let sync_state = self.get_sync_state(id)?; + self.delete_sync_state(&sync_state) + } +} diff --git a/src-tauri/yaak-models/src/queries/websocket_connections.rs b/src-tauri/yaak-models/src/queries/websocket_connections.rs new file mode 100644 index 000000000..4bcbd58e3 --- /dev/null +++ b/src-tauri/yaak-models/src/queries/websocket_connections.rs @@ -0,0 +1,97 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{WebsocketConnection, WebsocketConnectionIden, WebsocketConnectionState}; +use crate::queries::base::MAX_HISTORY_ITEMS; +use crate::queries_legacy::UpdateSource; +use log::debug; +use sea_query::{Expr, Query, SqliteQueryBuilder}; +use sea_query_rusqlite::RusqliteBinder; + +impl<'a> DbContext<'a> { + pub fn get_websocket_connection(&self, id: &str) -> Result { + self.find_one(WebsocketConnectionIden::Id, id) + } + + pub fn delete_all_websocket_connections_for_request( + &self, + request_id: &str, + source: &UpdateSource, + ) -> Result<()> { + let responses = self.list_websocket_connections_for_request(request_id)?; + for m in responses { + self.delete(&m, source)?; + } + Ok(()) + } + + pub fn delete_all_websocket_connections_for_workspace( + &self, + workspace_id: &str, + source: &UpdateSource, + ) -> Result<()> { + let responses = self.list_websocket_connections_for_workspace(workspace_id)?; + for m in responses { + self.delete(&m, source)?; + } + Ok(()) + } + + pub fn list_websocket_connections_for_workspace( + &self, + workspace_id: &str, + ) -> Result> { + self.find_many(WebsocketConnectionIden::WorkspaceId, workspace_id, None) + } + + pub fn list_websocket_connections_for_request( + &self, + request_id: &str, + ) -> Result> { + self.find_many(WebsocketConnectionIden::RequestId, request_id, None) + } + + pub fn delete_websocket_connection( + &self, + websocket_connection: &WebsocketConnection, + source: &UpdateSource, + ) -> Result { + self.delete(websocket_connection, source) + } + + pub fn delete_websocket_connection_by_id( + &self, + id: &str, + source: &UpdateSource, + ) -> Result { + let websocket_connection = self.get_websocket_connection(id)?; + self.delete_websocket_connection(&websocket_connection, source) + } + + pub fn upsert_websocket_connection( + &self, + websocket_connection: &WebsocketConnection, + source: &UpdateSource, + ) -> Result { + let connections = + self.list_websocket_connections_for_request(&websocket_connection.request_id)?; + + for m in connections.iter().skip(MAX_HISTORY_ITEMS - 1) { + debug!("Deleting old websocket connection {}", websocket_connection.id); + self.delete_websocket_connection(&m, source)?; + } + + self.upsert(websocket_connection, source) + } + + pub fn cancel_pending_websocket_connections(&self) -> Result<()> { + let closed = serde_json::to_value(&WebsocketConnectionState::Closed)?; + let (sql, params) = Query::update() + .table(WebsocketConnectionIden::Table) + .values([(WebsocketConnectionIden::State, closed.as_str().into())]) + .cond_where(Expr::col(WebsocketConnectionIden::State).ne(closed.as_str())) + .build_rusqlite(SqliteQueryBuilder); + let mut stmt = self.conn.prepare(sql.as_str())?; + stmt.execute(&*params.as_params())?; + Ok(()) + } +} diff --git a/src-tauri/yaak-models/src/queries/websocket_events.rs b/src-tauri/yaak-models/src/queries/websocket_events.rs new file mode 100644 index 000000000..08fee311a --- /dev/null +++ b/src-tauri/yaak-models/src/queries/websocket_events.rs @@ -0,0 +1,25 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{ + WebsocketEvent, + WebsocketEventIden, +}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_websocket_event(&self, id: &str) -> Result { + self.find_one(WebsocketEventIden::Id, id) + } + + pub fn list_websocket_events(&self, connection_id: &str) -> Result> { + self.find_many(WebsocketEventIden::ConnectionId, connection_id, None) + } + + pub fn upsert_websocket_event( + &self, + websocket_event: &WebsocketEvent, + source: &UpdateSource, + ) -> Result { + self.upsert(websocket_event, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/websocket_requests.rs b/src-tauri/yaak-models/src/queries/websocket_requests.rs new file mode 100644 index 000000000..dd3ffa235 --- /dev/null +++ b/src-tauri/yaak-models/src/queries/websocket_requests.rs @@ -0,0 +1,51 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{WebsocketRequest, WebsocketRequestIden}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_websocket_request(&self, id: &str) -> Result> { + self.find_optional(WebsocketRequestIden::Id, id) + } + + pub fn list_websocket_requests(&self, workspace_id: &str) -> Result> { + self.find_many(WebsocketRequestIden::WorkspaceId, workspace_id, None) + } + + pub fn delete_websocket_request( + &self, + websocket_request: &WebsocketRequest, + source: &UpdateSource, + ) -> Result { + self.delete_all_websocket_connections_for_request(websocket_request.id.as_str(), source)?; + self.delete(websocket_request, source) + } + + pub fn delete_websocket_request_by_id( + &self, + id: &str, + source: &UpdateSource, + ) -> Result { + let request = self.get_websocket_request(id)?.unwrap(); + self.delete_websocket_request(&request, source) + } + + pub fn duplicate_websocket_request( + &self, + websocket_request: &WebsocketRequest, + source: &UpdateSource, + ) -> Result { + let mut websocket_request = websocket_request.clone(); + websocket_request.id = "".to_string(); + websocket_request.sort_priority = websocket_request.sort_priority + 0.001; + self.upsert(&websocket_request, source) + } + + pub fn upsert_websocket_request( + &self, + websocket_request: &WebsocketRequest, + source: &UpdateSource, + ) -> Result { + self.upsert(websocket_request, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/workspace_metas.rs b/src-tauri/yaak-models/src/queries/workspace_metas.rs new file mode 100644 index 000000000..c9c2415a0 --- /dev/null +++ b/src-tauri/yaak-models/src/queries/workspace_metas.rs @@ -0,0 +1,36 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{Workspace, WorkspaceMeta, WorkspaceMetaIden}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_workspace_meta(&self, workspace: &Workspace) -> Result> { + self.find_optional(WorkspaceMetaIden::WorkspaceId, &workspace.id) + } + + pub fn get_or_create_workspace_meta( + &self, + workspace: &Workspace, + source: &UpdateSource, + ) -> Result { + let workspace_meta = self.get_workspace_meta(workspace)?; + if let Some(workspace_meta) = workspace_meta { + return Ok(workspace_meta); + } + + let workspace_meta = WorkspaceMeta { + workspace_id: workspace.to_owned().id, + ..Default::default() + }; + + self.upsert_workspace_meta(&workspace_meta, source) + } + + pub fn upsert_workspace_meta( + &self, + workspace_meta: &WorkspaceMeta, + source: &UpdateSource, + ) -> Result { + self.upsert(workspace_meta, source) + } +} diff --git a/src-tauri/yaak-models/src/queries/workspaces.rs b/src-tauri/yaak-models/src/queries/workspaces.rs new file mode 100644 index 000000000..743366ffd --- /dev/null +++ b/src-tauri/yaak-models/src/queries/workspaces.rs @@ -0,0 +1,52 @@ +use crate::error::Result; +use crate::manager::DbContext; +use crate::models::{ + Folder, FolderIden, GrpcRequest, GrpcRequestIden, HttpRequest, HttpRequestIden, + WebsocketRequest, WebsocketRequestIden, Workspace, WorkspaceIden, +}; +use crate::queries_legacy::UpdateSource; + +impl<'a> DbContext<'a> { + pub fn get_workspace(&self, id: &str) -> Result { + self.find_one(WorkspaceIden::Id, id) + } + + pub fn list_workspaces(&self) -> Result> { + self.find_all() + } + + pub fn delete_workspace( + &self, + workspace: &Workspace, + source: &UpdateSource, + ) -> Result { + for folder in self.find_many::(FolderIden::WorkspaceId, &workspace.id, None)? { + self.delete_folder(&folder, source)?; + } + for request in + self.find_many::(HttpRequestIden::WorkspaceId, &workspace.id, None)? + { + self.delete_http_request(&request, source)?; + } + for request in + self.find_many::(GrpcRequestIden::WorkspaceId, &workspace.id, None)? + { + self.delete_grpc_request(&request, source)?; + } + for request in + self.find_many::(WebsocketRequestIden::FolderId, &workspace.id, None)? + { + self.delete_websocket_request(&request, source)?; + } + self.delete(workspace, source) + } + + pub fn delete_workspace_by_id(&self, id: &str, source: &UpdateSource) -> Result { + let workspace = self.get_workspace(id)?; + self.delete_workspace(&workspace, source) + } + + pub fn upsert_workspace(&self, w: &Workspace, source: &UpdateSource) -> Result { + self.upsert(w, source) + } +} diff --git a/src-tauri/yaak-models/src/queries_legacy.rs b/src-tauri/yaak-models/src/queries_legacy.rs new file mode 100644 index 000000000..f0b256fb0 --- /dev/null +++ b/src-tauri/yaak-models/src/queries_legacy.rs @@ -0,0 +1,150 @@ +use crate::error::Result; +use crate::manager::QueryManagerExt; +use crate::models::{AnyModel, Environment, Folder, GrpcRequest, HttpRequest, ModelType, WebsocketRequest, Workspace, WorkspaceIden}; +use chrono::{NaiveDateTime, Utc}; +use log::warn; +use nanoid::nanoid; +use serde::{Deserialize, Serialize}; +use tauri::{AppHandle, Listener, Runtime, WebviewWindow}; +use ts_rs::TS; + +pub fn generate_model_id(model: ModelType) -> String { + let id = generate_id(); + format!("{}_{}", model.id_prefix(), id) +} + +pub fn generate_id() -> String { + let alphabet: [char; 57] = [ + '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', + 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', + ]; + + nanoid!(10, &alphabet) +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export, export_to = "gen_models.ts")] +pub struct ModelPayload { + pub model: AnyModel, + pub update_source: UpdateSource, + pub change: ModelChangeEvent, +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +#[serde(rename_all = "snake_case", tag = "type")] +#[ts(export, export_to = "gen_models.ts")] +pub enum ModelChangeEvent { + Upsert, + Delete, +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +#[serde(rename_all = "snake_case", tag = "type")] +#[ts(export, export_to = "gen_models.ts")] +pub enum UpdateSource { + Sync, + Window { label: String }, + Plugin, + Background, + Import, +} + +impl UpdateSource { + pub fn from_window(window: &WebviewWindow) -> Self { + Self::Window { + label: window.label().to_string(), + } + } +} + +pub fn listen_to_model_delete(app_handle: &AppHandle, handler: F) +where + F: Fn(ModelPayload) + Send + 'static, + R: Runtime, +{ + app_handle.listen_any("deleted_model", move |e| { + match serde_json::from_str(e.payload()) { + Ok(payload) => handler(payload), + Err(e) => { + warn!("Failed to deserialize deleted model {}", e); + return; + } + }; + }); +} + +pub fn listen_to_model_upsert(app_handle: &AppHandle, handler: F) +where + F: Fn(ModelPayload) + Send + 'static, + R: Runtime, +{ + app_handle.listen_any("upserted_model", move |e| { + match serde_json::from_str(e.payload()) { + Ok(payload) => handler(payload), + Err(e) => { + warn!("Failed to deserialize upserted model {}", e); + return; + } + }; + }); +} + +#[derive(Default, Debug, Deserialize, Serialize)] +#[serde(default, rename_all = "camelCase")] +pub struct WorkspaceExport { + pub yaak_version: String, + pub yaak_schema: i64, + pub timestamp: NaiveDateTime, + pub resources: BatchUpsertResult, +} + +#[derive(Default, Debug, Deserialize, Serialize)] +#[serde(default, rename_all = "camelCase")] +pub struct BatchUpsertResult { + pub workspaces: Vec, + pub environments: Vec, + pub folders: Vec, + pub http_requests: Vec, + pub grpc_requests: Vec, + pub websocket_requests: Vec, +} + +pub async fn get_workspace_export_resources( + app_handle: &AppHandle, + workspace_ids: Vec<&str>, + include_environments: bool, +) -> Result { + let mut data = WorkspaceExport { + yaak_version: app_handle.package_info().version.clone().to_string(), + yaak_schema: 3, + timestamp: Utc::now().naive_utc(), + resources: BatchUpsertResult { + workspaces: Vec::new(), + environments: Vec::new(), + folders: Vec::new(), + http_requests: Vec::new(), + grpc_requests: Vec::new(), + websocket_requests: Vec::new(), + }, + }; + + let db = app_handle.queries().connect().await?; + for workspace_id in workspace_ids { + data.resources.workspaces.push(db.find_one(WorkspaceIden::Id, workspace_id)?); + data.resources.environments.append(&mut db.list_environments(workspace_id)?); + data.resources.folders.append(&mut db.list_folders(workspace_id)?); + data.resources.http_requests.append(&mut db.list_http_requests(workspace_id)?); + data.resources.grpc_requests.append(&mut db.list_grpc_requests(workspace_id)?); + data.resources.websocket_requests.append(&mut db.list_websocket_requests(workspace_id)?); + } + + // Nuke environments if we don't want them + if !include_environments { + data.resources.environments.clear(); + } + + Ok(data) +} diff --git a/src-tauri/yaak-plugins/src/manager.rs b/src-tauri/yaak-plugins/src/manager.rs index ed8a7ffdb..6c8c5c0b1 100644 --- a/src-tauri/yaak-plugins/src/manager.rs +++ b/src-tauri/yaak-plugins/src/manager.rs @@ -14,7 +14,7 @@ use crate::events::{ use crate::nodejs::start_nodejs_plugin_runtime; use crate::plugin_handle::PluginHandle; use crate::server_ws::PluginRuntimeServerWebsocket; -use log::{info, warn}; +use log::{error, info, warn}; use std::collections::HashMap; use std::env; use std::path::PathBuf; @@ -25,9 +25,11 @@ use tauri::{AppHandle, Manager, Runtime, WebviewWindow}; use tokio::fs::read_dir; use tokio::net::TcpListener; use tokio::sync::{mpsc, Mutex}; -use tokio::time::timeout; -use yaak_models::queries::{generate_id, list_plugins}; +use tokio::time::{timeout, Instant}; +use yaak_models::manager::QueryManagerExt; +use yaak_models::queries_legacy::generate_id; use yaak_templates::error::Error::RenderError; +use yaak_templates::error::Result as TemplateResult; #[derive(Clone)] pub struct PluginManager { @@ -157,7 +159,8 @@ impl PluginManager { }) .collect(); - let plugins = list_plugins(app_handle).await.unwrap_or_default(); + let plugins = + app_handle.queries().connect().await.unwrap().list_plugins().unwrap_or_default(); let installed_plugin_dirs: Vec = plugins .iter() .map(|p| PluginCandidate { @@ -208,7 +211,7 @@ impl PluginManager { // Boot the plugin let event = timeout( - Duration::from_secs(2), + Duration::from_secs(5), self.send_to_plugin_and_wait( window_context, &plugin_handle, @@ -239,12 +242,14 @@ impl PluginManager { app_handle: &AppHandle, window_context: &WindowContext, ) -> Result<()> { + let start = Instant::now(); let candidates = self.list_plugin_dirs(app_handle).await; for candidate in candidates.clone() { // First remove the plugin if it exists if let Some(plugin) = self.get_plugin_by_dir(candidate.dir.as_str()).await { if let Err(e) = self.remove_plugin(window_context, &plugin).await { - warn!("Failed to remove plugin {} {e:?}", candidate.dir); + error!("Failed to remove plugin {} {e:?}", candidate.dir); + continue; } } if let Err(e) = self @@ -255,15 +260,13 @@ impl PluginManager { } } + let plugins = self.plugins.lock().await; + let names = plugins.iter().map(|p| p.dir.to_string()).collect::>(); info!( - "Initialized all plugins:\n - {}", - self.plugins - .lock() - .await - .iter() - .map(|p| p.dir.to_string()) - .collect::>() - .join("\n - "), + "Initialized {} plugins in {:?}:\n - {}", + plugins.len(), + start.elapsed(), + names.join("\n - "), ); Ok(()) @@ -598,7 +601,7 @@ impl PluginManager { fn_name: &str, args: HashMap, purpose: RenderPurpose, - ) -> yaak_templates::error::Result { + ) -> TemplateResult { let req = CallTemplateFunctionRequest { name: fn_name.to_string(), args: CallTemplateFunctionArgs { @@ -615,13 +618,14 @@ impl PluginManager { let value = events.into_iter().find_map(|e| match e.payload { InternalEventPayload::CallTemplateFunctionResponse(CallTemplateFunctionResponse { value, - }) => value, + }) => Some(value), _ => None, }); match value { - None => Err(RenderError(format!("Template function not found {fn_name}"))), - Some(v) => Ok(v), + None => Err(RenderError(format!("Template function {fn_name}(…) not found "))), + Some(Some(v)) => Ok(v), // Plugin returned string + Some(None) => Ok("".to_string()), // Plugin returned null } } diff --git a/src-tauri/yaak-sync/permissions/schemas/schema.json b/src-tauri/yaak-sync/permissions/schemas/schema.json index df0342cc8..d72d12bf0 100644 --- a/src-tauri/yaak-sync/permissions/schemas/schema.json +++ b/src-tauri/yaak-sync/permissions/schemas/schema.json @@ -49,7 +49,7 @@ "minimum": 1.0 }, "description": { - "description": "Human-readable description of what the permission does. Tauri convention is to use

headings in markdown content for Tauri documentation generation purposes.", + "description": "Human-readable description of what the permission does. Tauri convention is to use `

` headings in markdown content for Tauri documentation generation purposes.", "type": [ "string", "null" @@ -111,7 +111,7 @@ "type": "string" }, "description": { - "description": "Human-readable description of what the permission does. Tauri internal convention is to use

headings in markdown content for Tauri documentation generation purposes.", + "description": "Human-readable description of what the permission does. Tauri internal convention is to use `

` headings in markdown content for Tauri documentation generation purposes.", "type": [ "string", "null" diff --git a/src-tauri/yaak-sync/src/models.rs b/src-tauri/yaak-sync/src/models.rs index e1c20a120..50f4c09d2 100644 --- a/src-tauri/yaak-sync/src/models.rs +++ b/src-tauri/yaak-sync/src/models.rs @@ -126,7 +126,8 @@ impl TryFrom for SyncModel { AnyModel::WebsocketConnection(m) => return Err(UnknownModel(m.model)), AnyModel::WebsocketEvent(m) => return Err(UnknownModel(m.model)), AnyModel::WorkspaceMeta(m) => return Err(UnknownModel(m.model)), + AnyModel::SyncState(m) => return Err(UnknownModel(m.model)), }; Ok(m) } -} +} \ No newline at end of file diff --git a/src-tauri/yaak-sync/src/sync.rs b/src-tauri/yaak-sync/src/sync.rs index b7482c8dd..111d0de7d 100644 --- a/src-tauri/yaak-sync/src/sync.rs +++ b/src-tauri/yaak-sync/src/sync.rs @@ -11,13 +11,9 @@ use tokio::fs; use tokio::fs::File; use tokio::io::AsyncWriteExt; use ts_rs::TS; +use yaak_models::manager::QueryManagerExt; use yaak_models::models::{SyncState, WorkspaceMeta}; -use yaak_models::queries::{ - batch_upsert, delete_environment, delete_folder, delete_grpc_request, delete_http_request, - delete_sync_state, delete_websocket_request, delete_workspace, get_workspace_export_resources, - get_workspace_meta, list_sync_states_for_workspace, upsert_sync_state, upsert_workspace_meta, - UpdateSource, -}; +use yaak_models::queries_legacy::{get_workspace_export_resources, UpdateSource}; #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "camelCase", tag = "type")] @@ -115,12 +111,14 @@ pub(crate) async fn get_db_candidates( .into_iter() .map(|m| (m.id(), m)) .collect(); - let sync_states: HashMap<_, _> = - list_sync_states_for_workspace(app_handle, workspace_id, sync_dir) - .await? - .into_iter() - .map(|s| (s.model_id.clone(), s)) - .collect(); + let sync_states: HashMap<_, _> = app_handle + .queries() + .connect() + .await? + .list_sync_states_for_workspace(workspace_id, sync_dir)? + .into_iter() + .map(|s| (s.model_id.clone(), s)) + .collect(); // 1. Add candidates for models (created/modified/unmodified) let mut candidates: Vec = models @@ -442,41 +440,47 @@ pub(crate) async fn apply_sync_ops( }); } - let upserted_models = batch_upsert( - app_handle, - workspaces_to_upsert, - environments_to_upsert, - folders_to_upsert, - http_requests_to_upsert, - grpc_requests_to_upsert, - websocket_requests_to_upsert, - &UpdateSource::Sync, - ) - .await?; + let upserted_models = app_handle + .queries() + .with_tx(|tx| { + tx.batch_upsert( + workspaces_to_upsert, + environments_to_upsert, + folders_to_upsert, + http_requests_to_upsert, + grpc_requests_to_upsert, + websocket_requests_to_upsert, + &UpdateSource::Sync, + ) + }) + .await?; // Ensure we creat WorkspaceMeta models for each new workspace, with the appropriate sync dir let sync_dir_string = sync_dir.to_string_lossy().to_string(); + let db = app_handle.queries().connect().await?; for workspace in upserted_models.workspaces { - let r = match get_workspace_meta(app_handle, &workspace).await { + let r = match db.get_workspace_meta(&workspace) { Ok(Some(m)) => { if m.setting_sync_dir == Some(sync_dir_string.clone()) { // We don't need to update if unchanged continue; } - let wm = WorkspaceMeta { - setting_sync_dir: Some(sync_dir.to_string_lossy().to_string()), - ..m - }; - upsert_workspace_meta(app_handle, wm, &UpdateSource::Sync).await + db.upsert_workspace_meta( + &WorkspaceMeta { + setting_sync_dir: Some(sync_dir.to_string_lossy().to_string()), + ..m + }, + &UpdateSource::Sync, + ) } - Ok(None) => { - let wm = WorkspaceMeta { + Ok(None) => db.upsert_workspace_meta( + &WorkspaceMeta { workspace_id: workspace_id.to_string(), setting_sync_dir: Some(sync_dir.to_string_lossy().to_string()), ..Default::default() - }; - upsert_workspace_meta(app_handle, wm, &UpdateSource::Sync).await - } + }, + &UpdateSource::Sync, + ), Err(e) => Err(e), }; @@ -527,7 +531,7 @@ pub(crate) async fn apply_sync_state_ops( flushed_at: Utc::now().naive_utc(), ..Default::default() }; - upsert_sync_state(app_handle, sync_state).await?; + app_handle.queries().connect().await?.upsert_sync_state(&sync_state)?; } SyncStateOp::Update { state: sync_state, @@ -541,10 +545,10 @@ pub(crate) async fn apply_sync_state_ops( flushed_at: Utc::now().naive_utc(), ..sync_state }; - upsert_sync_state(app_handle, sync_state).await?; + app_handle.queries().connect().await?.upsert_sync_state(&sync_state)?; } SyncStateOp::Delete { state } => { - delete_sync_state(app_handle, state.id.as_str()).await?; + app_handle.queries().connect().await?.delete_sync_state(&state)?; } } } @@ -557,24 +561,25 @@ fn derive_model_filename(m: &SyncModel) -> PathBuf { } async fn delete_model(app_handle: &AppHandle, model: &SyncModel) -> Result<()> { + let db = app_handle.queries().connect().await?; match model { SyncModel::Workspace(m) => { - delete_workspace(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; + db.delete_workspace(&m, &UpdateSource::Sync)?; } SyncModel::Environment(m) => { - delete_environment(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; + db.delete_environment(&m, &UpdateSource::Sync)?; } SyncModel::Folder(m) => { - delete_folder(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; + db.delete_folder(&m, &UpdateSource::Sync)?; } SyncModel::HttpRequest(m) => { - delete_http_request(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; + db.delete_http_request(&m, &UpdateSource::Sync)?; } SyncModel::GrpcRequest(m) => { - delete_grpc_request(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; + db.delete_grpc_request(&m, &UpdateSource::Sync)?; } SyncModel::WebsocketRequest(m) => { - delete_websocket_request(app_handle, m.id.as_str(), &UpdateSource::Sync).await?; + db.delete_websocket_request(&m, &UpdateSource::Sync)?; } }; Ok(()) diff --git a/src-tauri/yaak-ws/permissions/schemas/schema.json b/src-tauri/yaak-ws/permissions/schemas/schema.json index 9aea6c8a8..c11c3eee5 100644 --- a/src-tauri/yaak-ws/permissions/schemas/schema.json +++ b/src-tauri/yaak-ws/permissions/schemas/schema.json @@ -49,7 +49,7 @@ "minimum": 1.0 }, "description": { - "description": "Human-readable description of what the permission does. Tauri convention is to use

headings in markdown content for Tauri documentation generation purposes.", + "description": "Human-readable description of what the permission does. Tauri convention is to use `

` headings in markdown content for Tauri documentation generation purposes.", "type": [ "string", "null" @@ -111,7 +111,7 @@ "type": "string" }, "description": { - "description": "Human-readable description of what the permission does. Tauri internal convention is to use

headings in markdown content for Tauri documentation generation purposes.", + "description": "Human-readable description of what the permission does. Tauri internal convention is to use `

` headings in markdown content for Tauri documentation generation purposes.", "type": [ "string", "null" diff --git a/src-tauri/yaak-ws/src/commands.rs b/src-tauri/yaak-ws/src/commands.rs index b8e533fee..9e7afa4fd 100644 --- a/src-tauri/yaak-ws/src/commands.rs +++ b/src-tauri/yaak-ws/src/commands.rs @@ -10,15 +10,12 @@ use tokio::sync::{mpsc, Mutex}; use tokio_tungstenite::tungstenite::http::HeaderValue; use tokio_tungstenite::tungstenite::Message; use yaak_http::apply_path_placeholders; +use yaak_models::manager::QueryManagerExt; use yaak_models::models::{ HttpResponseHeader, WebsocketConnection, WebsocketConnectionState, WebsocketEvent, WebsocketEventType, WebsocketRequest, }; -use yaak_models::queries; -use yaak_models::queries::{ - get_base_environment, get_cookie_jar, get_environment, get_websocket_connection, - get_websocket_request, upsert_websocket_connection, upsert_websocket_event, UpdateSource, -}; +use yaak_models::queries_legacy::UpdateSource; use yaak_plugins::events::{ CallHttpAuthenticationRequest, HttpHeader, RenderPurpose, WindowContext, }; @@ -31,8 +28,11 @@ pub(crate) async fn upsert_request( app_handle: AppHandle, window: WebviewWindow, ) -> Result { - Ok(queries::upsert_websocket_request(&app_handle, request, &UpdateSource::from_window(&window)) - .await?) + Ok(app_handle + .queries() + .connect() + .await? + .upsert_websocket_request(&request, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -41,12 +41,9 @@ pub(crate) async fn duplicate_request( app_handle: AppHandle, window: WebviewWindow, ) -> Result { - Ok(queries::duplicate_websocket_request( - &app_handle, - request_id, - &UpdateSource::from_window(&window), - ) - .await?) + let db = app_handle.queries().connect().await?; + let request = db.get_websocket_request(request_id)?.unwrap(); + Ok(db.duplicate_websocket_request(&request, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -55,7 +52,11 @@ pub(crate) async fn delete_request( app_handle: AppHandle, window: WebviewWindow, ) -> Result { - Ok(queries::delete_websocket_request(&app_handle, request_id, &UpdateSource::from_window(&window)).await?) + Ok(app_handle + .queries() + .connect() + .await? + .delete_websocket_request_by_id(request_id, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -64,8 +65,11 @@ pub(crate) async fn delete_connection( app_handle: AppHandle, window: WebviewWindow, ) -> Result { - Ok(queries::delete_websocket_connection(&app_handle, connection_id, &UpdateSource::from_window(&window)) - .await?) + Ok(app_handle + .queries() + .connect() + .await? + .delete_websocket_connection_by_id(connection_id, &UpdateSource::from_window(&window))?) } #[tauri::command] @@ -74,8 +78,10 @@ pub(crate) async fn delete_connections( app_handle: AppHandle, window: WebviewWindow, ) -> Result<()> { - Ok(queries::delete_all_websocket_connections(&app_handle, request_id, &UpdateSource::from_window(&window)) - .await?) + Ok(app_handle.queries().connect().await?.delete_all_websocket_connections_for_request( + request_id, + &UpdateSource::from_window(&window), + )?) } #[tauri::command] @@ -83,7 +89,7 @@ pub(crate) async fn list_events( connection_id: &str, app_handle: AppHandle, ) -> Result> { - Ok(queries::list_websocket_events(&app_handle, connection_id).await?) + Ok(app_handle.queries().connect().await?.list_websocket_events(connection_id)?) } #[tauri::command] @@ -91,7 +97,7 @@ pub(crate) async fn list_requests( workspace_id: &str, app_handle: AppHandle, ) -> Result> { - Ok(queries::list_websocket_requests(&app_handle, workspace_id).await?) + Ok(app_handle.queries().connect().await?.list_websocket_requests(workspace_id)?) } #[tauri::command] @@ -99,7 +105,11 @@ pub(crate) async fn list_connections( workspace_id: &str, app_handle: AppHandle, ) -> Result> { - Ok(queries::list_websocket_connections_for_workspace(&app_handle, workspace_id).await?) + Ok(app_handle + .queries() + .connect() + .await? + .list_websocket_connections_for_workspace(workspace_id)?) } #[tauri::command] @@ -110,16 +120,23 @@ pub(crate) async fn send( window: WebviewWindow, ws_manager: State<'_, Mutex>, ) -> Result { - let connection = get_websocket_connection(&app_handle, connection_id).await?; - let unrendered_request = get_websocket_request(&app_handle, &connection.request_id) - .await? - .ok_or(GenericError("WebSocket Request not found".to_string()))?; + let (connection, unrendered_request) = { + let db = app_handle.queries().connect().await?; + let connection = db.get_websocket_connection(connection_id)?; + let unrendered_request = db + .get_websocket_request(&connection.request_id)? + .ok_or(GenericError("WebSocket Request not found".to_string()))?; + (connection, unrendered_request) + }; let environment = match environment_id { - Some(id) => Some(get_environment(&app_handle, id).await?), + Some(id) => Some(app_handle.queries().connect().await?.get_environment(id)?), None => None, }; - let base_environment = - get_base_environment(&app_handle, &unrendered_request.workspace_id).await?; + let base_environment = app_handle + .queries() + .connect() + .await? + .get_base_environment(&unrendered_request.workspace_id)?; let request = render_request( &unrendered_request, &base_environment, @@ -135,9 +152,8 @@ pub(crate) async fn send( let mut ws_manager = ws_manager.lock().await; ws_manager.send(&connection.id, Message::Text(request.message.clone().into())).await?; - upsert_websocket_event( - &app_handle, - WebsocketEvent { + app_handle.queries().connect().await?.upsert_websocket_event( + &WebsocketEvent { connection_id: connection.id.clone(), request_id: request.id.clone(), workspace_id: connection.workspace_id.clone(), @@ -147,9 +163,7 @@ pub(crate) async fn send( ..Default::default() }, &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + )?; Ok(connection) } @@ -161,17 +175,17 @@ pub(crate) async fn close( window: WebviewWindow, ws_manager: State<'_, Mutex>, ) -> Result { - let connection = get_websocket_connection(&app_handle, connection_id).await?; - let connection = upsert_websocket_connection( - &app_handle, - &WebsocketConnection { - state: WebsocketConnectionState::Closing, - ..connection - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + let connection = { + let db = app_handle.queries().connect().await?; + let connection = db.get_websocket_connection(connection_id)?; + db.upsert_websocket_connection( + &WebsocketConnection { + state: WebsocketConnectionState::Closing, + ..connection + }, + &UpdateSource::from_window(&window), + )? + }; let mut ws_manager = ws_manager.lock().await; if let Err(e) = ws_manager.close(&connection.id).await { @@ -191,15 +205,21 @@ pub(crate) async fn connect( plugin_manager: State<'_, PluginManager>, ws_manager: State<'_, Mutex>, ) -> Result { - let unrendered_request = get_websocket_request(&app_handle, request_id) + let unrendered_request = app_handle + .queries() + .connect() .await? + .get_websocket_request(request_id)? .ok_or(GenericError("Failed to find GRPC request".to_string()))?; let environment = match environment_id { - Some(id) => Some(get_environment(&app_handle, id).await?), + Some(id) => Some(app_handle.queries().connect().await?.get_environment(id)?), None => None, }; - let base_environment = - get_base_environment(&app_handle, &unrendered_request.workspace_id).await?; + let base_environment = app_handle + .queries() + .connect() + .await? + .get_base_environment(&unrendered_request.workspace_id)?; let request = render_request( &unrendered_request, &base_environment, @@ -242,20 +262,18 @@ pub(crate) async fn connect( // TODO: Handle cookies let _cookie_jar = match cookie_jar_id { - Some(id) => Some(get_cookie_jar(&app_handle, id).await?), + Some(id) => Some(app_handle.queries().connect().await?.get_cookie_jar(id)?), None => None, }; - let connection = upsert_websocket_connection( - &app_handle, + let connection = app_handle.queries().connect().await?.upsert_websocket_connection( &WebsocketConnection { workspace_id: request.workspace_id.clone(), request_id: request_id.to_string(), ..Default::default() }, &UpdateSource::from_window(&window), - ) - .await?; + )?; let (receive_tx, mut receive_rx) = mpsc::channel::(128); let mut ws_manager = ws_manager.lock().await; @@ -278,22 +296,19 @@ pub(crate) async fn connect( { Ok(r) => r, Err(e) => { - return Ok(upsert_websocket_connection( - &app_handle, + return Ok(app_handle.queries().connect().await?.upsert_websocket_connection( &WebsocketConnection { error: Some(format!("{e:?}")), state: WebsocketConnectionState::Closed, ..connection }, &UpdateSource::from_window(&window), - ) - .await?); + )?); } }; - upsert_websocket_event( - &app_handle, - WebsocketEvent { + app_handle.queries().connect().await?.upsert_websocket_event( + &WebsocketEvent { connection_id: connection.id.clone(), request_id: request.id.clone(), workspace_id: connection.workspace_id.clone(), @@ -302,9 +317,7 @@ pub(crate) async fn connect( ..Default::default() }, &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + )?; let response_headers = response .headers() @@ -315,8 +328,7 @@ pub(crate) async fn connect( }) .collect::>(); - let connection = upsert_websocket_connection( - &app_handle, + let connection = app_handle.queries().connect().await?.upsert_websocket_connection( &WebsocketConnection { state: WebsocketConnectionState::Connected, headers: response_headers, @@ -325,8 +337,7 @@ pub(crate) async fn connect( ..connection }, &UpdateSource::from_window(&window), - ) - .await?; + )?; { let connection_id = connection.id.clone(); @@ -340,59 +351,68 @@ pub(crate) async fn connect( has_written_close = true; } - upsert_websocket_event( - &app_handle, - WebsocketEvent { - connection_id: connection_id.clone(), - request_id: request_id.clone(), - workspace_id: workspace_id.clone(), - is_server: true, - message_type: match message { - Message::Text(_) => WebsocketEventType::Text, - Message::Binary(_) => WebsocketEventType::Binary, - Message::Ping(_) => WebsocketEventType::Ping, - Message::Pong(_) => WebsocketEventType::Pong, - Message::Close(_) => WebsocketEventType::Close, - // Raw frame will never happen during a read - Message::Frame(_) => WebsocketEventType::Frame, + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_websocket_event( + &WebsocketEvent { + connection_id: connection_id.clone(), + request_id: request_id.clone(), + workspace_id: workspace_id.clone(), + is_server: true, + message_type: match message { + Message::Text(_) => WebsocketEventType::Text, + Message::Binary(_) => WebsocketEventType::Binary, + Message::Ping(_) => WebsocketEventType::Ping, + Message::Pong(_) => WebsocketEventType::Pong, + Message::Close(_) => WebsocketEventType::Close, + // Raw frame will never happen during a read + Message::Frame(_) => WebsocketEventType::Frame, + }, + message: message.into_data().into(), + ..Default::default() }, - message: message.into_data().into(), - ..Default::default() - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); + &UpdateSource::from_window(&window), + ) + .unwrap(); } info!("Websocket connection closed"); if !has_written_close { - upsert_websocket_event( - &app_handle, - WebsocketEvent { - connection_id: connection_id.clone(), - request_id: request_id.clone(), - workspace_id: workspace_id.clone(), - is_server: true, - message_type: WebsocketEventType::Close, - ..Default::default() + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_websocket_event( + &WebsocketEvent { + connection_id: connection_id.clone(), + request_id: request_id.clone(), + workspace_id: workspace_id.clone(), + is_server: true, + message_type: WebsocketEventType::Close, + ..Default::default() + }, + &UpdateSource::from_window(&window), + ) + .unwrap(); + } + app_handle + .queries() + .connect() + .await + .unwrap() + .upsert_websocket_connection( + &WebsocketConnection { + workspace_id: request.workspace_id.clone(), + request_id: request_id.to_string(), + state: WebsocketConnectionState::Closed, + ..connection }, &UpdateSource::from_window(&window), ) - .await .unwrap(); - } - upsert_websocket_connection( - &app_handle, - &WebsocketConnection { - workspace_id: request.workspace_id.clone(), - request_id: request_id.to_string(), - state: WebsocketConnectionState::Closed, - ..connection - }, - &UpdateSource::from_window(&window), - ) - .await - .unwrap(); }); } diff --git a/src-web/components/HttpResponsePane.tsx b/src-web/components/HttpResponsePane.tsx index b746f6aa6..878f717c8 100644 --- a/src-web/components/HttpResponsePane.tsx +++ b/src-web/components/HttpResponsePane.tsx @@ -86,6 +86,7 @@ export function HttpResponsePane({ style, className, activeRequestId }: Props) { }, [activeRequestId, setActiveTabs], ); + console.log("ACTIVE RESPONSE", activeResponse); return (
('cmd_create_http_request', { + return invokeCmd('cmd_upsert_http_request', { request: { workspaceId, ...patch }, }); }, diff --git a/src-web/hooks/useSyncModelStores.ts b/src-web/hooks/useSyncModelStores.ts index bc9d51f24..a209bd0f2 100644 --- a/src-web/hooks/useSyncModelStores.ts +++ b/src-web/hooks/useSyncModelStores.ts @@ -178,7 +178,6 @@ export function removeModelByKv(model: KeyValue) { } function shouldIgnoreModel({ model, updateSource }: ModelPayload) { - console.log('HELLO', updateSource); // Never ignore updates from non-user sources if (updateSource.type !== 'window') { return false; diff --git a/src-web/hooks/useUpdateAnyHttpRequest.ts b/src-web/hooks/useUpdateAnyHttpRequest.ts index f65faa3e1..881586b17 100644 --- a/src-web/hooks/useUpdateAnyHttpRequest.ts +++ b/src-web/hooks/useUpdateAnyHttpRequest.ts @@ -21,7 +21,7 @@ export function useUpdateAnyHttpRequest() { const patchedRequest = typeof update === 'function' ? update(request) : { ...request, ...update }; - return invokeCmd('cmd_update_http_request', { request: patchedRequest }); + return invokeCmd('cmd_upsert_http_request', { request: patchedRequest }); }, onSuccess: async (request) => { setHttpRequests(updateModelList(request)); diff --git a/src-web/lib/tauri.ts b/src-web/lib/tauri.ts index a354fb7ea..d0236f56d 100644 --- a/src-web/lib/tauri.ts +++ b/src-web/lib/tauri.ts @@ -8,7 +8,6 @@ type TauriCmd = | 'cmd_create_cookie_jar' | 'cmd_create_environment' | 'cmd_create_grpc_request' - | 'cmd_create_http_request' | 'cmd_curl_to_request' | 'cmd_delete_all_grpc_connections' | 'cmd_delete_all_http_responses' @@ -75,7 +74,7 @@ type TauriCmd = | 'cmd_update_environment' | 'cmd_update_folder' | 'cmd_update_grpc_request' - | 'cmd_update_http_request' + | 'cmd_upsert_http_request' | 'cmd_update_settings' | 'cmd_update_workspace' | 'cmd_update_workspace_meta'; From 8801936ad228496853f9a3ea265b21e5cbb36785 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 09:13:56 -0700 Subject: [PATCH 120/996] Bump vite from 6.0.6 to 6.0.12 (#191) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 859 +++++++++---------------------------------- src-web/package.json | 2 +- 2 files changed, 173 insertions(+), 688 deletions(-) diff --git a/package-lock.json b/package-lock.json index 56c3d059a..15ce1299a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -695,9 +695,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", "cpu": [ "ppc64" ], @@ -707,15 +707,14 @@ "os": [ "aix" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", "cpu": [ "arm" ], @@ -725,15 +724,14 @@ "os": [ "android" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", "cpu": [ "arm64" ], @@ -743,15 +741,14 @@ "os": [ "android" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", "cpu": [ "x64" ], @@ -761,15 +758,14 @@ "os": [ "android" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", "cpu": [ "arm64" ], @@ -779,15 +775,14 @@ "os": [ "darwin" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", "cpu": [ "x64" ], @@ -797,15 +792,14 @@ "os": [ "darwin" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", "cpu": [ "arm64" ], @@ -815,15 +809,14 @@ "os": [ "freebsd" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", "cpu": [ "x64" ], @@ -833,15 +826,14 @@ "os": [ "freebsd" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", "cpu": [ "arm" ], @@ -851,15 +843,14 @@ "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", "cpu": [ "arm64" ], @@ -869,15 +860,14 @@ "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", "cpu": [ "ia32" ], @@ -887,15 +877,14 @@ "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", "cpu": [ "loong64" ], @@ -905,15 +894,14 @@ "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", "cpu": [ "mips64el" ], @@ -923,15 +911,14 @@ "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", "cpu": [ "ppc64" ], @@ -941,15 +928,14 @@ "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", "cpu": [ "riscv64" ], @@ -959,15 +945,14 @@ "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", "cpu": [ "s390x" ], @@ -977,15 +962,14 @@ "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", "cpu": [ "x64" ], @@ -995,9 +979,8 @@ "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/netbsd-arm64": { @@ -1018,9 +1001,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", "cpu": [ "x64" ], @@ -1030,9 +1013,8 @@ "os": [ "netbsd" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/openbsd-arm64": { @@ -1053,9 +1035,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", "cpu": [ "x64" ], @@ -1065,15 +1047,14 @@ "os": [ "openbsd" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", "cpu": [ "x64" ], @@ -1083,15 +1064,14 @@ "os": [ "sunos" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", "cpu": [ "arm64" ], @@ -1101,15 +1081,14 @@ "os": [ "win32" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", "cpu": [ "ia32" ], @@ -1119,15 +1098,14 @@ "os": [ "win32" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", "cpu": [ "x64" ], @@ -1137,9 +1115,8 @@ "os": [ "win32" ], - "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -6037,43 +6014,61 @@ "optional": true }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/esbuild/node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/escalade": { @@ -14897,22 +14892,21 @@ } }, "node_modules/vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.12.tgz", + "integrity": "sha512-gzLogvGSgX2xyAt0J5qhJ7SmdO5aLdShABkU8Ev7dIl8AcrlFSLcj9GHReSq9pGJF/q5C4CZKdtDlkC6DyvQ3w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -14921,19 +14915,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.4.0" + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -14954,6 +14954,12 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, @@ -15781,550 +15787,29 @@ "postcss-nesting": "^13.0.0", "react-devtools": "^5.3.1", "tailwindcss": "^3.4.10", - "vite": "6.0.6", + "vite": "6.0.12", "vite-plugin-static-copy": "^2.2.0", "vite-plugin-svgr": "^4.3.0", "vite-plugin-top-level-await": "^1.4.4" } }, - "src-web/node_modules/@esbuild/aix-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", - "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/android-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", - "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", - "cpu": [ - "arm" + "src-web/node_modules/nanoid": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz", + "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } ], - "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/android-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", - "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/android-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", - "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/darwin-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", - "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/darwin-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", - "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/freebsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", - "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/freebsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", - "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/linux-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", - "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/linux-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", - "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/linux-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", - "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/linux-loong64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", - "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/linux-mips64el": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", - "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/linux-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", - "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/linux-riscv64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", - "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/linux-s390x": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", - "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/linux-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", - "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/netbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", - "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/openbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", - "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/openbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", - "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/sunos-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", - "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/win32-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", - "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/win32-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", - "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/@esbuild/win32-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", - "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "src-web/node_modules/esbuild": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", - "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.24.2", - "@esbuild/android-arm": "0.24.2", - "@esbuild/android-arm64": "0.24.2", - "@esbuild/android-x64": "0.24.2", - "@esbuild/darwin-arm64": "0.24.2", - "@esbuild/darwin-x64": "0.24.2", - "@esbuild/freebsd-arm64": "0.24.2", - "@esbuild/freebsd-x64": "0.24.2", - "@esbuild/linux-arm": "0.24.2", - "@esbuild/linux-arm64": "0.24.2", - "@esbuild/linux-ia32": "0.24.2", - "@esbuild/linux-loong64": "0.24.2", - "@esbuild/linux-mips64el": "0.24.2", - "@esbuild/linux-ppc64": "0.24.2", - "@esbuild/linux-riscv64": "0.24.2", - "@esbuild/linux-s390x": "0.24.2", - "@esbuild/linux-x64": "0.24.2", - "@esbuild/netbsd-arm64": "0.24.2", - "@esbuild/netbsd-x64": "0.24.2", - "@esbuild/openbsd-arm64": "0.24.2", - "@esbuild/openbsd-x64": "0.24.2", - "@esbuild/sunos-x64": "0.24.2", - "@esbuild/win32-arm64": "0.24.2", - "@esbuild/win32-ia32": "0.24.2", - "@esbuild/win32-x64": "0.24.2" - } - }, - "src-web/node_modules/nanoid": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz", - "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.js" - }, + "bin": { + "nanoid": "bin/nanoid.js" + }, "engines": { "node": "^18 || >=20" } - }, - "src-web/node_modules/vite": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.6.tgz", - "integrity": "sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.24.2", - "postcss": "^8.4.49", - "rollup": "^4.23.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } } } } diff --git a/src-web/package.json b/src-web/package.json index d5af7a995..02080233f 100644 --- a/src-web/package.json +++ b/src-web/package.json @@ -92,7 +92,7 @@ "postcss-nesting": "^13.0.0", "react-devtools": "^5.3.1", "tailwindcss": "^3.4.10", - "vite": "6.0.6", + "vite": "6.0.12", "vite-plugin-static-copy": "^2.2.0", "vite-plugin-svgr": "^4.3.0", "vite-plugin-top-level-await": "^1.4.4" From 596912014024d6432fc8e403e6cdbf3a822c9725 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 25 Mar 2025 09:23:26 -0700 Subject: [PATCH 121/996] Fix folder upsert --- src-tauri/yaak-models/src/models.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index cd8cbdcda..1de6522fd 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -3,7 +3,7 @@ use crate::models::HttpRequestIden::{ Authentication, AuthenticationType, Body, BodyType, CreatedAt, Description, FolderId, Headers, Method, Name, SortPriority, UpdatedAt, Url, UrlParameters, WorkspaceId, }; -use crate::queries_legacy::{generate_model_id, UpdateSource}; +use crate::queries_legacy::UpdateSource; use chrono::{NaiveDateTime, Utc}; use rusqlite::Row; use sea_query::{enum_def, IntoIden, IntoTableRef, SimpleExpr}; @@ -556,7 +556,7 @@ impl UpsertModelInfo for Folder { } fn get_id(&self) -> String { - generate_model_id(ModelType::TypeFolder) + self.id.clone() } fn insert_values( From bac3968aacbaab774eff50055fe79a2f5555e91d Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 25 Mar 2025 09:23:45 -0700 Subject: [PATCH 122/996] Revert scrollbar fix --- src-web/main.css | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src-web/main.css b/src-web/main.css index 5e7a4b374..134f914f0 100644 --- a/src-web/main.css +++ b/src-web/main.css @@ -58,15 +58,11 @@ .hide-scrollbars { &::-webkit-scrollbar-corner, &::-webkit-scrollbar { - display: NONE !important; + @apply hidden !important; } } - /* Style the scrollbars - * Mac doesn't like this (especially in CodeMirror) so we only do it on non-macos platforms. On Mac, - * styling the scrollbar seems to cause them to not show up at all most of the time - */ - html:not([data-platform="macos"]) { + html { * { ::-webkit-scrollbar-corner, ::-webkit-scrollbar { From 006284b99c8c64d3bbfbda77fe822e10728c4185 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 25 Mar 2025 09:38:15 -0700 Subject: [PATCH 123/996] Fix scrollbars --- src-web/components/sidebar/Sidebar.tsx | 2 +- src-web/main.css | 51 ++++++++++++-------------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src-web/components/sidebar/Sidebar.tsx b/src-web/components/sidebar/Sidebar.tsx index d8dc3371b..4b2fe11e7 100644 --- a/src-web/components/sidebar/Sidebar.tsx +++ b/src-web/components/sidebar/Sidebar.tsx @@ -360,7 +360,7 @@ export function Sidebar({ className }: Props) { 'h-full grid grid-rows-[minmax(0,1fr)_auto]', )} > -
+
); } diff --git a/src-web/components/RequestMethodDropdown.tsx b/src-web/components/RequestMethodDropdown.tsx index f690618e6..39048447f 100644 --- a/src-web/components/RequestMethodDropdown.tsx +++ b/src-web/components/RequestMethodDropdown.tsx @@ -32,7 +32,7 @@ export const RequestMethodDropdown = memo(function RequestMethodDropdown({ onChange, className, }: Props) { - const extraItems = useMemo( + const itemsAfter = useMemo( () => [ { key: 'custom', @@ -57,7 +57,7 @@ export const RequestMethodDropdown = memo(function RequestMethodDropdown({ ); return ( - + diff --git a/src-web/components/ResponseHeaders.tsx b/src-web/components/ResponseHeaders.tsx index 463f8bfb9..d084165e8 100644 --- a/src-web/components/ResponseHeaders.tsx +++ b/src-web/components/ResponseHeaders.tsx @@ -1,4 +1,5 @@ import type { HttpResponse } from '@yaakapp-internal/models'; +import { useMemo } from 'react'; import { KeyValueRow, KeyValueRows } from './core/KeyValueRow'; interface Props { @@ -6,10 +7,14 @@ interface Props { } export function ResponseHeaders({ response }: Props) { + const sortedHeaders = useMemo( + () => [...response.headers].sort((a, b) => a.name.localeCompare(b.name)), + [response.headers], + ); return (
- {response.headers.map((h, i) => ( + {sortedHeaders.map((h, i) => ( {h.value} diff --git a/src-web/components/SelectFile.tsx b/src-web/components/SelectFile.tsx index 0fe78d9d9..3cbfb998a 100644 --- a/src-web/components/SelectFile.tsx +++ b/src-web/components/SelectFile.tsx @@ -1,9 +1,12 @@ import { open } from '@tauri-apps/plugin-dialog'; import classNames from 'classnames'; import mime from 'mime'; +import type { ReactNode } from 'react'; import type { ButtonProps } from './core/Button'; import { Button } from './core/Button'; import { IconButton } from './core/IconButton'; +import { IconTooltip } from './core/IconTooltip'; +import { Label } from './core/Label'; import { HStack } from './core/Stacks'; type Props = Omit & { @@ -12,6 +15,8 @@ type Props = Omit & { directory?: boolean; inline?: boolean; noun?: string; + help?: ReactNode; + label?: ReactNode; }; // Special character to insert ltr text in rtl element @@ -25,6 +30,8 @@ export function SelectFile({ directory, noun, size = 'sm', + label, + help, ...props }: Props) { const handleClick = async () => { @@ -46,41 +53,55 @@ export function SelectFile({ const selectOrChange = (filePath ? 'Change ' : 'Select ') + itemLabel; return ( - - - - {!inline && ( - <> - {filePath && ( - +
+ {label && ( + + )} + + + + {!inline && ( + <> + {filePath && ( + )} - > - {rtlEscapeChar} - {filePath ?? `No ${itemLabel.toLowerCase()} selected`} -
- - )} -
+
+ {rtlEscapeChar} + {filePath ?? `No ${itemLabel.toLowerCase()} selected`} +
+ {filePath == null && help && !label && } + + )} + +
); } diff --git a/src-web/components/Settings/SettingsGeneral.tsx b/src-web/components/Settings/SettingsGeneral.tsx index 008087940..44411d492 100644 --- a/src-web/components/Settings/SettingsGeneral.tsx +++ b/src-web/components/Settings/SettingsGeneral.tsx @@ -37,7 +37,7 @@ export function SettingsGeneral() { value={settings.updateChannel} onChange={(updateChannel) => patchModel(settings, { updateChannel })} options={[ - { label: 'Stable (less frequent)', value: 'stable' }, + { label: 'Stable', value: 'stable' }, { label: 'Beta (more frequent)', value: 'beta' }, ]} /> @@ -52,7 +52,7 @@ export function SettingsGeneral() {
+ patchModel(workspace, { name })} - stateKey={`name.${workspace.id}`} /> patchModel(workspace, { description })} heightMode="auto" /> - - patchModel(workspaceMeta, { settingSyncDir: filePath })} - /> - - - + patchModel(workspaceMeta, { settingSyncDir: filePath })} + /> + + + + + ); } diff --git a/src-web/components/core/BadgeButton.tsx b/src-web/components/core/BadgeButton.tsx new file mode 100644 index 000000000..349e94ba9 --- /dev/null +++ b/src-web/components/core/BadgeButton.tsx @@ -0,0 +1,6 @@ +import type { ButtonProps } from './Button'; +import { Button } from './Button'; + +export function BadgeButton(props: ButtonProps) { + return + + + ); + }, [dropdownItems, isEncryptionEnabled, props.disabled, state.obscured, state.security, tint]); + + const type = state.obscured ? 'password' : 'text'; + + return ( + + ); +} diff --git a/src-web/components/core/Label.tsx b/src-web/components/core/Label.tsx index d3a377462..148a8fa65 100644 --- a/src-web/components/core/Label.tsx +++ b/src-web/components/core/Label.tsx @@ -1,5 +1,6 @@ import classNames from 'classnames'; -import type { HTMLAttributes } from 'react'; +import type { HTMLAttributes, ReactNode } from 'react'; +import { IconTooltip } from './IconTooltip'; export function Label({ htmlFor, @@ -8,21 +9,24 @@ export function Label({ visuallyHidden, tags = [], required, + help, ...props }: HTMLAttributes & { - htmlFor: string; + htmlFor: string | null; required?: boolean; tags?: string[]; visuallyHidden?: boolean; + children: ReactNode; + help?: ReactNode; }) { return ( ); } diff --git a/src-web/components/core/PairEditor.tsx b/src-web/components/core/PairEditor.tsx index 6f678a77a..7d4946541 100644 --- a/src-web/components/core/PairEditor.tsx +++ b/src-web/components/core/PairEditor.tsx @@ -55,7 +55,7 @@ export type PairEditorProps = { valueAutocompleteFunctions?: boolean; valueAutocompleteVariables?: boolean; valuePlaceholder?: string; - valueType?: 'text' | 'password'; + valueType?: InputProps['type'] | ((pair: Pair) => InputProps['type']); valueValidate?: InputProps['validate']; }; @@ -78,7 +78,6 @@ const MAX_INITIAL_PAIRS = 50; export const PairEditor = forwardRef(function PairEditor( { - stateKey, allowFileValues, allowMultilineValues, className, @@ -91,6 +90,7 @@ export const PairEditor = forwardRef(function Pa noScroll, onChange, pairs: originalPairs, + stateKey, valueAutocomplete, valueAutocompleteFunctions, valueAutocompleteVariables, @@ -124,7 +124,7 @@ export const PairEditor = forwardRef(function Pa const p = originalPairs[i]; if (!p) continue; // Make TS happy if (isPairEmpty(p)) continue; - newPairs.push({ ...p, id: p.id ?? generateId() }); + newPairs.push(ensurePairId(p)); } // Add empty last pair if there is none @@ -555,7 +555,7 @@ function PairEditorRow({ name={`value[${index}]`} onChange={handleChangeValueText} onFocus={handleFocus} - type={isLast ? 'text' : valueType} + type={isLast ? 'text' : typeof valueType === 'function' ? valueType(pair) : valueType} placeholder={valuePlaceholder ?? 'value'} autocomplete={valueAutocomplete?.(pair.name)} autocompleteFunctions={valueAutocompleteFunctions} @@ -615,7 +615,7 @@ function FileActionsDropdown({ [onChangeFile, onChangeText], ); - const extraItems = useMemo( + const itemsAfter = useMemo( () => [ { label: 'Edit Multi-Line', @@ -664,7 +664,7 @@ function FileActionsDropdown({ value={pair.isFile ? 'file' : 'text'} onChange={onChange} items={fileItems} - extraItems={extraItems} + itemsAfter={itemsAfter} > @@ -672,12 +672,7 @@ function FileActionsDropdown({ } function emptyPair(): PairWithId { - return { - enabled: true, - name: '', - value: '', - id: generateId(), - }; + return ensurePairId({ enabled: true, name: '', value: '' }); } function isPairEmpty(pair: Pair): boolean { @@ -723,3 +718,12 @@ function MultilineEditDialog({
); } + +// eslint-disable-next-line react-refresh/only-export-components +export function ensurePairId(p: Pair): PairWithId { + if (typeof p.id === 'string') { + return p as PairWithId; + } else { + return { ...p, id: p.id ?? generateId() }; + } +} diff --git a/src-web/components/core/PlainInput.tsx b/src-web/components/core/PlainInput.tsx index 24a854484..1d18a44e4 100644 --- a/src-web/components/core/PlainInput.tsx +++ b/src-web/components/core/PlainInput.tsx @@ -12,6 +12,7 @@ export type PlainInputProps = Omit['onFocus']; type?: 'text' | 'password' | 'number'; step?: number; + hideObscureToggle?: boolean; }; export function PlainInput({ @@ -31,8 +32,10 @@ export function PlainInput({ onPaste, required, rightSlot, + hideObscureToggle, size = 'md', type = 'text', + tint, validate, autoSelect, placeholder, @@ -115,6 +118,16 @@ export function PlainInput({ size === 'xs' && 'min-h-xs', )} > + {tint != null && ( +
+ )} {leftSlot} - {type === 'password' && ( + {type === 'password' && !hideObscureToggle && ( = export interface RadioDropdownProps { value: T; onChange: (value: T) => void; + itemsBefore?: DropdownItem[]; items: RadioDropdownItem[]; - extraItems?: DropdownItem[]; + itemsAfter?: DropdownItem[]; children: DropdownProps['children']; } export function RadioDropdown({ value, items, - extraItems, + itemsAfter, + itemsBefore, onChange, children, }: RadioDropdownProps) { const dropdownItems = useMemo( () => [ + ...((itemsBefore ? [...itemsBefore, { type: 'separator' }] : []) as DropdownItem[]), ...items.map((item) => { if (item.type === 'separator') { return item; @@ -44,9 +47,9 @@ export function RadioDropdown({ } as DropdownItem; } }), - ...((extraItems ? [{ type: 'separator' }, ...extraItems] : []) as DropdownItem[]), + ...((itemsAfter ? [{ type: 'separator' }, ...itemsAfter] : []) as DropdownItem[]), ], - [items, extraItems, value, onChange], + [itemsBefore, items, itemsAfter, value, onChange], ); return ( diff --git a/src-web/components/core/SegmentedControl.tsx b/src-web/components/core/SegmentedControl.tsx index af73b2b9f..dccf4342b 100644 --- a/src-web/components/core/SegmentedControl.tsx +++ b/src-web/components/core/SegmentedControl.tsx @@ -10,9 +10,15 @@ interface Props { onChange: (value: T) => void; value: T; name: string; + className?: string; } -export function SegmentedControl({ value, onChange, options }: Props) { +export function SegmentedControl({ + value, + onChange, + options, + className, +}: Props) { const [selectedValue, setSelectedValue] = useStateWithDeps(value, [value]); const containerRef = useRef(null); return ( @@ -21,7 +27,12 @@ export function SegmentedControl({ value, onChange, options }: role="group" dir="ltr" space={0.5} - className="bg-surface-highlight rounded-md mb-auto opacity-0 group-focus-within/markdown:opacity-100 group-hover/markdown:opacity-100 transition-opacity transform-gpu" + className={classNames( + className, + 'bg-surface-highlight rounded-md mb-auto opacity-0', + 'transition-opacity transform-gpu', + 'group-focus-within/markdown:opacity-100 group-hover/markdown:opacity-100', + )} onKeyDown={(e) => { const selectedIndex = options.findIndex((o) => o.value === selectedValue); if (e.key === 'ArrowRight') { diff --git a/src-web/components/core/SplitLayout.tsx b/src-web/components/core/SplitLayout.tsx index 4ba480440..fc854c82a 100644 --- a/src-web/components/core/SplitLayout.tsx +++ b/src-web/components/core/SplitLayout.tsx @@ -144,7 +144,7 @@ export function SplitLayout({ const containerQueryReady = size.width > 0 || size.height > 0; return ( -
+
{containerQueryReady && ( <> {firstSlot({ style: areaL, orientation: vertical ? 'vertical' : 'horizontal' })} diff --git a/src-web/components/core/Tooltip.tsx b/src-web/components/core/Tooltip.tsx new file mode 100644 index 000000000..ec96ea8bc --- /dev/null +++ b/src-web/components/core/Tooltip.tsx @@ -0,0 +1,135 @@ +import classNames from 'classnames'; +import type { CSSProperties, KeyboardEvent, ReactNode } from 'react'; +import React, { useRef, useState } from 'react'; +import { generateId } from '../../lib/generateId'; +import { Portal } from '../Portal'; + +export interface TooltipProps { + children: ReactNode; + content: ReactNode; + size?: 'md' | 'lg'; +} + +const hiddenStyles: CSSProperties = { + left: -99999, + top: -99999, + visibility: 'hidden', + pointerEvents: 'none', + opacity: 0, +}; + +export function Tooltip({ children, content, size = 'md' }: TooltipProps) { + const [isOpen, setIsOpen] = useState(); + const triggerRef = useRef(null); + const tooltipRef = useRef(null); + const showTimeout = useRef(); + + const handleOpenImmediate = () => { + if (triggerRef.current == null || tooltipRef.current == null) return; + clearTimeout(showTimeout.current); + setIsOpen(undefined); + const triggerRect = triggerRef.current.getBoundingClientRect(); + const tooltipRect = tooltipRef.current.getBoundingClientRect(); + const docRect = document.documentElement.getBoundingClientRect(); + const styles: CSSProperties = { + bottom: docRect.height - triggerRect.top, + left: Math.max(0, triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2), + maxHeight: triggerRect.top, + }; + setIsOpen(styles); + }; + + const handleOpen = () => { + clearTimeout(showTimeout.current); + showTimeout.current = setTimeout(handleOpenImmediate, 500); + }; + + const handleClose = () => { + clearTimeout(showTimeout.current); + setIsOpen(undefined); + }; + + const handleToggleImmediate = () => { + if (isOpen) handleClose(); + else handleOpenImmediate(); + }; + + const handleKeyDown = (e: KeyboardEvent) => { + if (isOpen && e.key === 'Escape') { + e.preventDefault(); + e.stopPropagation(); + handleClose(); + } + }; + + const id = useRef(`tooltip-${generateId()}`); + + return ( + <> + + + + + + ); +} + +function Triangle({ className }: { className?: string }) { + return ( + + + + + ); +} diff --git a/src-web/components/sidebar/SidebarItemContextMenu.tsx b/src-web/components/sidebar/SidebarItemContextMenu.tsx index 36f25f7e1..0b3fd5f5f 100644 --- a/src-web/components/sidebar/SidebarItemContextMenu.tsx +++ b/src-web/components/sidebar/SidebarItemContextMenu.tsx @@ -12,9 +12,9 @@ import { useMoveToWorkspace } from '../../hooks/useMoveToWorkspace'; import { useSendAnyHttpRequest } from '../../hooks/useSendAnyHttpRequest'; import { useSendManyRequests } from '../../hooks/useSendManyRequests'; import { deleteModelWithConfirm } from '../../lib/deleteModelWithConfirm'; -import { duplicateRequestAndNavigate } from '../../lib/deleteRequestAndNavigate'; import { showDialog } from '../../lib/dialog'; +import { duplicateRequestAndNavigate } from '../../lib/duplicateRequestAndNavigate'; import { renameModelWithPrompt } from '../../lib/renameModelWithPrompt'; import type { DropdownItem } from '../core/Dropdown'; import { ContextMenu } from '../core/Dropdown'; diff --git a/src-web/hooks/useCreateDropdownItems.tsx b/src-web/hooks/useCreateDropdownItems.tsx index caa04969f..250cd5355 100644 --- a/src-web/hooks/useCreateDropdownItems.tsx +++ b/src-web/hooks/useCreateDropdownItems.tsx @@ -1,15 +1,14 @@ -import { createWorkspaceModel } from '@yaakapp-internal/models'; import { useAtomValue } from 'jotai'; import { useMemo } from 'react'; import { createFolder } from '../commands/commands'; import type { DropdownItem } from '../components/core/Dropdown'; import { Icon } from '../components/core/Icon'; +import { createRequestAndNavigate } from '../lib/createRequestAndNavigate'; import { generateId } from '../lib/generateId'; import { jotaiStore } from '../lib/jotai'; import { BODY_TYPE_GRAPHQL } from '../lib/model_util'; import { activeRequestAtom } from './useActiveRequest'; import { activeWorkspaceIdAtom } from './useActiveWorkspace'; -import { useCreateHttpRequest } from './useCreateHttpRequest'; export function useCreateDropdownItems({ hideFolder, @@ -20,7 +19,6 @@ export function useCreateDropdownItems({ hideIcons?: boolean; folderId?: string | null | 'active-folder'; } = {}): DropdownItem[] { - const { mutate: createHttpRequest } = useCreateHttpRequest(); const workspaceId = useAtomValue(activeWorkspaceIdAtom); const items = useMemo((): DropdownItem[] => { @@ -33,15 +31,15 @@ export function useCreateDropdownItems({ { label: 'HTTP', leftSlot: hideIcons ? undefined : , - onSelect: () => { - createHttpRequest({ folderId }); - }, + onSelect: () => createRequestAndNavigate({ model: 'http_request', workspaceId, folderId }), }, { label: 'GraphQL', leftSlot: hideIcons ? undefined : , onSelect: () => - createHttpRequest({ + createRequestAndNavigate({ + model: 'http_request', + workspaceId, folderId, bodyType: BODY_TYPE_GRAPHQL, method: 'POST', @@ -51,12 +49,13 @@ export function useCreateDropdownItems({ { label: 'gRPC', leftSlot: hideIcons ? undefined : , - onSelect: () => createWorkspaceModel({ model: 'grpc_request', workspaceId, folderId }), + onSelect: () => createRequestAndNavigate({ model: 'grpc_request', workspaceId, folderId }), }, { label: 'WebSocket', leftSlot: hideIcons ? undefined : , - onSelect: () => createWorkspaceModel({ model: 'websocket_request', workspaceId, folderId }), + onSelect: () => + createRequestAndNavigate({ model: 'websocket_request', workspaceId, folderId }), }, ...((hideFolder ? [] @@ -69,7 +68,7 @@ export function useCreateDropdownItems({ }, ]) as DropdownItem[]), ]; - }, [createHttpRequest, folderIdOption, hideFolder, hideIcons, workspaceId]); + }, [folderIdOption, hideFolder, hideIcons, workspaceId]); return items; } diff --git a/src-web/hooks/useCreateGrpcRequest.ts b/src-web/hooks/useCreateGrpcRequest.ts deleted file mode 100644 index 0e583ebbe..000000000 --- a/src-web/hooks/useCreateGrpcRequest.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { GrpcRequest } from '@yaakapp-internal/models'; -import { createWorkspaceModel } from '@yaakapp-internal/models'; -import { jotaiStore } from '../lib/jotai'; -import { router } from '../lib/router'; -import { activeRequestAtom } from './useActiveRequest'; -import { activeWorkspaceIdAtom } from './useActiveWorkspace'; -import { useFastMutation } from './useFastMutation'; - -export function useCreateGrpcRequest() { - return useFastMutation< - string, - unknown, - Partial> - >({ - mutationKey: ['create_grpc_request'], - mutationFn: async (patch) => { - const workspaceId = jotaiStore.get(activeWorkspaceIdAtom); - if (workspaceId === null) { - throw new Error("Cannot create grpc request when there's no active workspace"); - } - const activeRequest = jotaiStore.get(activeRequestAtom); - if (patch.sortPriority === undefined) { - if (activeRequest != null) { - // Place above currently active request - patch.sortPriority = activeRequest.sortPriority + 0.0001; - } else { - // Place at the very top - patch.sortPriority = -Date.now(); - } - } - patch.folderId = patch.folderId || activeRequest?.folderId; - return createWorkspaceModel({ model: 'grpc_request', workspaceId, ...patch }); - }, - onSuccess: async (requestId) => { - const workspaceId = jotaiStore.get(activeWorkspaceIdAtom); - if (workspaceId == null) return; - - await router.navigate({ - to: '/workspaces/$workspaceId', - params: { workspaceId }, - search: (prev) => ({ ...prev, request_id: requestId }), - }); - }, - }); -} diff --git a/src-web/hooks/useCreateHttpRequest.ts b/src-web/hooks/useCreateHttpRequest.ts deleted file mode 100644 index efff44125..000000000 --- a/src-web/hooks/useCreateHttpRequest.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { HttpRequest } from '@yaakapp-internal/models'; -import { createWorkspaceModel } from '@yaakapp-internal/models'; -import { jotaiStore } from '../lib/jotai'; -import { router } from '../lib/router'; -import { activeRequestAtom } from './useActiveRequest'; -import { activeWorkspaceIdAtom } from './useActiveWorkspace'; -import { useFastMutation } from './useFastMutation'; - -export function useCreateHttpRequest() { - return useFastMutation>({ - mutationKey: ['create_http_request'], - mutationFn: async (patch = {}) => { - const workspaceId = jotaiStore.get(activeWorkspaceIdAtom); - if (workspaceId == null) { - throw new Error("Cannot create request when there's no active workspace"); - } - - const activeRequest = jotaiStore.get(activeRequestAtom); - if (patch.sortPriority === undefined) { - if (activeRequest != null) { - // Place above currently active request - patch.sortPriority = activeRequest.sortPriority - 0.0001; - } else { - // Place at the very top - patch.sortPriority = -Date.now(); - } - } - patch.folderId = patch.folderId || activeRequest?.folderId; - return createWorkspaceModel({ model: 'http_request', workspaceId, ...patch }); - }, - onSuccess: async (requestId) => { - const workspaceId = jotaiStore.get(activeWorkspaceIdAtom); - if (workspaceId == null) return; - await router.navigate({ - to: '/workspaces/$workspaceId', - params: { workspaceId }, - search: (prev) => ({ ...prev, request_id: requestId }), - }); - }, - }); -} diff --git a/src-web/hooks/useImportData.tsx b/src-web/hooks/useImportData.tsx index e6241b8dc..3d10a3268 100644 --- a/src-web/hooks/useImportData.tsx +++ b/src-web/hooks/useImportData.tsx @@ -1,10 +1,4 @@ -import type { - Environment, - Folder, - GrpcRequest, - HttpRequest, - Workspace, -} from '@yaakapp-internal/models'; +import type { BatchUpsertResult } from '@yaakapp-internal/models'; import { Button } from '../components/core/Button'; import { FormattedError } from '../components/core/FormattedError'; import { VStack } from '../components/core/Stacks'; @@ -21,13 +15,7 @@ import { useFastMutation } from './useFastMutation'; export function useImportData() { const importData = async (filePath: string): Promise => { const activeWorkspace = jotaiStore.get(activeWorkspaceAtom); - const imported: { - workspaces: Workspace[]; - environments: Environment[]; - folders: Folder[]; - httpRequests: HttpRequest[]; - grpcRequests: GrpcRequest[]; - } = await invokeCmd('cmd_import_data', { + const imported = await invokeCmd('cmd_import_data', { filePath, workspaceId: activeWorkspace?.id, }); @@ -40,15 +28,25 @@ export function useImportData() { size: 'sm', hideX: true, render: ({ hide }) => { - const { workspaces, environments, folders, httpRequests, grpcRequests } = imported; return (
    -
  • {pluralizeCount('Workspace', workspaces.length)}
  • -
  • {pluralizeCount('Environment', environments.length)}
  • -
  • {pluralizeCount('Folder', folders.length)}
  • -
  • {pluralizeCount('HTTP Request', httpRequests.length)}
  • -
  • {pluralizeCount('GRPC Request', grpcRequests.length)}
  • +
  • {pluralizeCount('Workspace', imported.workspaces.length)}
  • + {imported.environments.length > 0 && ( +
  • {pluralizeCount('Environment', imported.environments.length)}
  • + )} + {imported.folders.length > 0 && ( +
  • {pluralizeCount('Folder', imported.folders.length)}
  • + )} + {imported.httpRequests.length > 0 && ( +
  • {pluralizeCount('HTTP Request', imported.httpRequests.length)}
  • + )} + {imported.grpcRequests.length > 0 && ( +
  • {pluralizeCount('GRPC Request', imported.grpcRequests.length)}
  • + )} + {imported.websocketRequests.length > 0 && ( +
  • {pluralizeCount('Websocket Request', imported.websocketRequests.length)}
  • + )}
- {rightSlot} + {outerRightSlot}
- {environment != null && ( - setShowContextMenu(null)} - items={[ - { - label: 'Rename', - leftSlot: , - onSelect: async () => { - const name = await showPrompt({ - id: 'rename-environment', - title: 'Rename Environment', - description: ( - <> - Enter a new name for {environment.name} - - ), - label: 'Name', - confirmText: 'Save', - placeholder: 'New Name', - defaultValue: environment.name, - }); - if (name == null) return; - await patchModel(environment, { name }); - }, + setShowContextMenu(null)} + items={[ + { + label: 'Rename', + leftSlot: , + hidden: environment.base, + onSelect: async () => { + const name = await showPrompt({ + id: 'rename-environment', + title: 'Rename Environment', + description: ( + <> + Enter a new name for {environment.name} + + ), + label: 'Name', + confirmText: 'Save', + placeholder: 'New Name', + defaultValue: environment.name, + }); + if (name == null) return; + await patchModel(environment, { name }); }, - { - color: 'danger', - label: 'Delete', - leftSlot: , - onSelect: async () => { - await deleteModelWithConfirm(environment); - onDelete?.(); - }, + }, + ...((duplicateEnvironment + ? [ + { + label: 'Duplicate', + leftSlot: , + onSelect: () => { + duplicateEnvironment?.(environment); + }, + }, + ] + : []) as DropdownItem[]), + { + label: `Make ${environment.public ? 'Private' : 'Sharable'}`, + leftSlot: , + rightSlot: ( + + Sharable environments will be included in Directory Sync or data export. It is + recommended to encrypt all variable values within sharable environments to + prevent accidentally leaking secrets. + + } + /> + ), + onSelect: async () => { + await patchModel(environment, { public: !environment.public }); }, - ]} - /> - )} + }, + ...((deleteEnvironment + ? [ + { + color: 'danger', + label: 'Delete', + leftSlot: , + onSelect: () => { + deleteEnvironment(environment); + }, + }, + ] + : []) as DropdownItem[]), + ]} + /> ); } + +const sharableTooltip = ( + +); diff --git a/src-web/components/ExportDataDialog.tsx b/src-web/components/ExportDataDialog.tsx index 5b01c2fb5..35d8dd2b7 100644 --- a/src-web/components/ExportDataDialog.tsx +++ b/src-web/components/ExportDataDialog.tsx @@ -1,5 +1,5 @@ import { save } from '@tauri-apps/plugin-dialog'; -import type { Workspace} from '@yaakapp-internal/models'; +import type { Workspace } from '@yaakapp-internal/models'; import { workspacesAtom } from '@yaakapp-internal/models'; import { useAtomValue } from 'jotai'; import { useCallback, useMemo, useState } from 'react'; @@ -41,12 +41,12 @@ function ExportDataDialogContent({ allWorkspaces: Workspace[]; activeWorkspace: Workspace; }) { - const [includeEnvironments, setIncludeEnvironments] = useState(false); + const [includePrivateEnvironments, setIncludePrivateEnvironments] = useState(false); const [selectedWorkspaces, setSelectedWorkspaces] = useState>({ [activeWorkspace.id]: true, }); - // Put active workspace first + // Put the active workspace first const workspaces = useMemo( () => [activeWorkspace, ...allWorkspaces.filter((w) => w.id !== activeWorkspace.id)], [activeWorkspace, allWorkspaces], @@ -73,11 +73,11 @@ function ExportDataDialogContent({ await invokeCmd('cmd_export_data', { workspaceIds: ids, exportPath, - includeEnvironments: includeEnvironments, + includePrivateEnvironments: includePrivateEnvironments, }); onHide(); onSuccess(exportPath); - }, [includeEnvironments, onHide, onSuccess, selectedWorkspaces, workspaces]); + }, [includePrivateEnvironments, onHide, onSuccess, selectedWorkspaces, workspaces]); const allSelected = workspaces.every((w) => selectedWorkspaces[w.id]); const numSelected = Object.values(selectedWorkspaces).filter(Boolean).length; @@ -129,9 +129,10 @@ function ExportDataDialogContent({ Extra Settings
diff --git a/src-web/components/GrpcResponsePane.tsx b/src-web/components/GrpcResponsePane.tsx index 106e1d030..157048fc5 100644 --- a/src-web/components/GrpcResponsePane.tsx +++ b/src-web/components/GrpcResponsePane.tsx @@ -1,10 +1,9 @@ import type { GrpcEvent, GrpcRequest } from '@yaakapp-internal/models'; import classNames from 'classnames'; import { format } from 'date-fns'; -import { useAtomValue , useSetAtom } from 'jotai'; +import { useAtomValue, useSetAtom } from 'jotai'; import type { CSSProperties } from 'react'; import { useEffect, useMemo, useRef, useState } from 'react'; -import { useCopy } from '../hooks/useCopy'; import { activeGrpcConnectionAtom, activeGrpcConnections, @@ -12,12 +11,14 @@ import { useGrpcEvents, } from '../hooks/usePinnedGrpcConnection'; import { useStateWithDeps } from '../hooks/useStateWithDeps'; +import { copyToClipboard } from '../lib/copy'; import { AutoScroller } from './core/AutoScroller'; import { Banner } from './core/Banner'; import { Button } from './core/Button'; +import { Editor } from './core/Editor/Editor'; +import { HotKeyList } from './core/HotKeyList'; import { Icon } from './core/Icon'; import { IconButton } from './core/IconButton'; -import { JsonAttributeTree } from './core/JsonAttributeTree'; import { KeyValueRow, KeyValueRows } from './core/KeyValueRow'; import { LoadingIcon } from './core/LoadingIcon'; import { Separator } from './core/Separator'; @@ -25,7 +26,6 @@ import { SplitLayout } from './core/SplitLayout'; import { HStack, VStack } from './core/Stacks'; import { EmptyStateText } from './EmptyStateText'; import { RecentGrpcConnectionsDropdown } from './RecentGrpcConnectionsDropdown'; -import { HotKeyList } from './core/HotKeyList'; interface Props { style?: CSSProperties; @@ -48,7 +48,6 @@ export function GrpcResponsePane({ style, methodType, activeRequest }: Props) { const activeConnection = useAtomValue(activeGrpcConnectionAtom); const events = useGrpcEvents(activeConnection?.id ?? null); const setPinnedGrpcConnectionId = useSetAtom(pinnedGrpcConnectionIdAtom); - const copy = useCopy(); const activeEvent = useMemo( () => events.find((m) => m.id === activeEventId) ?? null, @@ -136,7 +135,7 @@ export function GrpcResponsePane({ style, methodType, activeRequest }: Props) { title="Copy message" icon="copy" size="xs" - onClick={() => copy(activeEvent.content)} + onClick={() => copyToClipboard(activeEvent.content)} />
{!showLarge && activeEvent.content.length > 1000 * 1000 ? ( @@ -161,7 +160,13 @@ export function GrpcResponsePane({ style, methodType, activeRequest }: Props) {
) : ( - + )} ) : ( diff --git a/src-web/components/SettingsDropdown.tsx b/src-web/components/SettingsDropdown.tsx index a7d00b4e2..1ede3162e 100644 --- a/src-web/components/SettingsDropdown.tsx +++ b/src-web/components/SettingsDropdown.tsx @@ -74,13 +74,13 @@ export function SettingsDropdown() { { label: 'Feedback', leftSlot: , - rightSlot: , + rightSlot: , onSelect: () => openUrl('https://yaak.app/feedback'), }, { label: 'Changelog', leftSlot: , - rightSlot: , + rightSlot: , onSelect: () => openUrl(`https://yaak.app/changelog/${appInfo.version}`), }, ]} diff --git a/src-web/components/WebsocketResponsePane.tsx b/src-web/components/WebsocketResponsePane.tsx index f7900110b..4464031d6 100644 --- a/src-web/components/WebsocketResponsePane.tsx +++ b/src-web/components/WebsocketResponsePane.tsx @@ -4,7 +4,6 @@ import { format } from 'date-fns'; import { hexy } from 'hexy'; import { useAtomValue } from 'jotai'; import { useMemo, useRef, useState } from 'react'; -import { useCopy } from '../hooks/useCopy'; import { useFormatText } from '../hooks/useFormatText'; import { activeWebsocketConnectionAtom, @@ -14,6 +13,7 @@ import { } from '../hooks/usePinnedWebsocketConnection'; import { useStateWithDeps } from '../hooks/useStateWithDeps'; import { languageFromContentType } from '../lib/contentType'; +import { copyToClipboard } from '../lib/copy'; import { AutoScroller } from './core/AutoScroller'; import { Banner } from './core/Banner'; import { Button } from './core/Button'; @@ -41,7 +41,6 @@ export function WebsocketResponsePane({ activeRequest }: Props) { const activeConnection = useAtomValue(activeWebsocketConnectionAtom); const connections = useAtomValue(activeWebsocketConnectionsAtom); - const events = useWebsocketEvents(activeConnection?.id ?? null); const activeEvent = useMemo( @@ -63,7 +62,6 @@ export function WebsocketResponsePane({ activeRequest }: Props) { const language = languageFromContentType(null, message); const formattedMessage = useFormatText({ language, text: message, pretty: true }); - const copy = useCopy(); return ( copy(formattedMessage.data ?? '')} + onClick={() => copyToClipboard(formattedMessage.data ?? '')} /> )} diff --git a/src-web/components/WorkspaceEncryptionSetting.tsx b/src-web/components/WorkspaceEncryptionSetting.tsx index bdc4ff08e..8373c8555 100644 --- a/src-web/components/WorkspaceEncryptionSetting.tsx +++ b/src-web/components/WorkspaceEncryptionSetting.tsx @@ -29,15 +29,41 @@ export function WorkspaceEncryptionSetting({ size, expanded, onDone, onEnabledEn const workspace = useAtomValue(activeWorkspaceAtom); const workspaceMeta = useAtomValue(activeWorkspaceMetaAtom); + const [key, setKey] = useState<{ key: string | null; error: string | null } | null>(null); - if (workspace == null || workspaceMeta == null) { + useEffect(() => { + if (workspaceMeta == null) { + return; + } + + if (workspaceMeta?.encryptionKey == null) { + setKey({ key: null, error: null }); + return; + } + + revealWorkspaceKey(workspaceMeta.workspaceId).then( + (key) => { + setKey({ key, error: null }); + }, + (err) => { + setKey({ key: null, error: `${err}` }); + }, + ); + }, [setKey, workspaceMeta, workspaceMeta?.encryptionKey]); + + if (key == null || workspace == null || workspaceMeta == null) { return null; } - if (workspace.encryptionKeyChallenge && workspaceMeta.encryptionKey == null) { + // Prompt for key if it doesn't exist or could not be decrypted + if ( + key.error != null || + (workspace.encryptionKeyChallenge && workspaceMeta.encryptionKey == null) + ) { return ( { onDone?.(); onEnabledEncryption?.(); @@ -46,12 +72,13 @@ export function WorkspaceEncryptionSetting({ size, expanded, onDone, onEnabledEn ); } - if (workspaceMeta.encryptionKey) { + // Show the key if it exists + if (workspaceMeta.encryptionKey && key.key != null) { const keyRevealer = ( ); return ( @@ -63,10 +90,13 @@ export function WorkspaceEncryptionSetting({ size, expanded, onDone, onEnabledEn )} {keyRevealer} {onDone && ( - )} @@ -74,6 +104,7 @@ export function WorkspaceEncryptionSetting({ size, expanded, onDone, onEnabledEn ); } + // Show button to enable encryption return (
+ + + {workspaceId} + ); } diff --git a/src-web/components/core/BulkPairEditor.tsx b/src-web/components/core/BulkPairEditor.tsx index b956af821..9c67bcf4b 100644 --- a/src-web/components/core/BulkPairEditor.tsx +++ b/src-web/components/core/BulkPairEditor.tsx @@ -11,6 +11,7 @@ export function BulkPairEditor({ namePlaceholder, valuePlaceholder, forceUpdateKey, + forcedEnvironmentId, stateKey, }: Props) { const pairsText = useMemo(() => { @@ -36,6 +37,7 @@ export function BulkPairEditor({ autocompleteFunctions autocompleteVariables stateKey={`bulk_pair.${stateKey}`} + forcedEnvironmentId={forcedEnvironmentId} forceUpdateKey={forceUpdateKey} placeholder={`${namePlaceholder ?? 'name'}: ${valuePlaceholder ?? 'value'}`} defaultValue={pairsText} diff --git a/src-web/components/core/Dialog.tsx b/src-web/components/core/Dialog.tsx index c2604ae9b..ae0df4f5b 100644 --- a/src-web/components/core/Dialog.tsx +++ b/src-web/components/core/Dialog.tsx @@ -2,7 +2,6 @@ import classNames from 'classnames'; import * as m from 'motion/react-m'; import type { ReactNode } from 'react'; import { useMemo } from 'react'; -import { useKey } from 'react-use'; import { Overlay } from '../Overlay'; import { Heading } from './Heading'; import { IconButton } from './IconButton'; @@ -42,18 +41,9 @@ export function Dialog({ [description], ); - useKey( - 'Escape', - () => { - if (!open) return; - onClose?.(); - }, - {}, - [open], - ); - return ( + {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}
{ + // NOTE: We handle Escape on the element itself so that it doesn't close multiple + // dialogs and can be intercepted by children if needed. + if (e.key === 'Escape') { + onClose?.(); + e.stopPropagation(); + e.preventDefault(); + } + }} > - + {children} + ); } diff --git a/src-web/components/core/Dropdown.tsx b/src-web/components/core/Dropdown.tsx index 99fefc405..5d82c7ae9 100644 --- a/src-web/components/core/Dropdown.tsx +++ b/src-web/components/core/Dropdown.tsx @@ -1,6 +1,6 @@ import classNames from 'classnames'; -import * as m from 'motion/react-m'; import { atom } from 'jotai'; +import * as m from 'motion/react-m'; import type { CSSProperties, FocusEvent as ReactFocusEvent, @@ -34,9 +34,9 @@ import { Overlay } from '../Overlay'; import { Button } from './Button'; import { HotKey } from './HotKey'; import { Icon } from './Icon'; +import { LoadingIcon } from './LoadingIcon'; import { Separator } from './Separator'; import { HStack, VStack } from './Stacks'; -import { LoadingIcon } from './LoadingIcon'; export type DropdownItemSeparator = { type: 'separator'; diff --git a/src-web/components/core/Editor/Editor.tsx b/src-web/components/core/Editor/Editor.tsx index b82cb6bdc..86b89812f 100644 --- a/src-web/components/core/Editor/Editor.tsx +++ b/src-web/components/core/Editor/Editor.tsx @@ -26,7 +26,8 @@ import { useMemo, useRef, } from 'react'; -import { useActiveEnvironmentVariables } from '../../../hooks/useActiveEnvironmentVariables'; +import { activeEnvironmentIdAtom } from '../../../hooks/useActiveEnvironment'; +import { useEnvironmentVariables } from '../../../hooks/useEnvironmentVariables'; import { useRequestEditor } from '../../../hooks/useRequestEditor'; import { useTemplateFunctionCompletionOptions } from '../../../hooks/useTemplateFunctions'; import { showDialog } from '../../../lib/dialog'; @@ -69,6 +70,7 @@ export interface EditorProps { disableTabIndent?: boolean; disabled?: boolean; extraExtensions?: Extension[]; + forcedEnvironmentId?: string; forceUpdateKey?: string | number; format?: (v: string) => Promise; heightMode?: 'auto' | 'full'; @@ -108,6 +110,7 @@ export const Editor = forwardRef(function E disableTabIndent, disabled, extraExtensions, + forcedEnvironmentId, forceUpdateKey, format, heightMode, @@ -130,7 +133,9 @@ export const Editor = forwardRef(function E ) { const settings = useAtomValue(settingsAtom); - const allEnvironmentVariables = useActiveEnvironmentVariables(); + const activeEnvironmentId = useAtomValue(activeEnvironmentIdAtom); + const environmentId = forcedEnvironmentId ?? activeEnvironmentId ?? null; + const allEnvironmentVariables = useEnvironmentVariables(environmentId); const environmentVariables = autocompleteVariables ? allEnvironmentVariables : emptyVariables; const useTemplating = !!(autocompleteFunctions || autocompleteVariables || autocomplete); diff --git a/src-web/components/core/Icon.tsx b/src-web/components/core/Icon.tsx index 87c8c5586..aba15f74b 100644 --- a/src-web/components/core/Icon.tsx +++ b/src-web/components/core/Icon.tsx @@ -44,6 +44,7 @@ const icons = { eye_closed: lucide.EyeOffIcon, file_code: lucide.FileCodeIcon, filter: lucide.FilterIcon, + flame: lucide.FlameIcon, flask: lucide.FlaskConicalIcon, folder: lucide.FolderIcon, folder_git: lucide.FolderGitIcon, @@ -138,7 +139,7 @@ export const Icon = memo(function Icon({ size === 'xs' && 'h-3 w-3', size === '2xs' && 'h-2.5 w-2.5', color === 'default' && 'inherit', - color === 'danger' && 'text-danger!', + color === 'danger' && 'text-danger', color === 'warning' && 'text-warning', color === 'notice' && 'text-notice', color === 'info' && 'text-info', diff --git a/src-web/components/core/IconTooltip.tsx b/src-web/components/core/IconTooltip.tsx index 38ec1b660..c6072ec14 100644 --- a/src-web/components/core/IconTooltip.tsx +++ b/src-web/components/core/IconTooltip.tsx @@ -7,13 +7,25 @@ import { Tooltip } from './Tooltip'; type Props = Omit & { icon?: IconProps['icon']; iconSize?: IconProps['size']; + iconColor?: IconProps['color']; className?: string; }; -export function IconTooltip({ content, icon = 'info', iconSize, ...tooltipProps }: Props) { +export function IconTooltip({ + content, + icon = 'info', + iconColor, + iconSize, + ...tooltipProps +}: Props) { return ( - + ); } diff --git a/src-web/components/core/Input.tsx b/src-web/components/core/Input.tsx index 1f33eaa81..95c270c95 100644 --- a/src-web/components/core/Input.tsx +++ b/src-web/components/core/Input.tsx @@ -30,11 +30,13 @@ import { Icon } from './Icon'; import { IconButton } from './IconButton'; import { Label } from './Label'; import { HStack } from './Stacks'; +import { copyToClipboard } from '../../lib/copy'; export type InputProps = Pick< EditorProps, | 'language' | 'autocomplete' + | 'forcedEnvironmentId' | 'forceUpdateKey' | 'disabled' | 'autoFocus' @@ -387,19 +389,32 @@ function EncryptionInput({ const dropdownItems = useMemo( () => [ { - label: state.obscured ? 'Reveal value' : 'Conceal value', + label: state.obscured ? 'Reveal' : 'Conceal', disabled: isEncryptionEnabled && state.fieldType === 'text', leftSlot: , onSelect: () => setState((s) => ({ ...s, obscured: !s.obscured })), }, + { + label: 'Copy', + leftSlot: , + hidden: !state.value, + onSelect: () => copyToClipboard(state.value ?? ''), + }, { type: 'separator' }, { - label: state.fieldType === 'text' ? 'Encrypt Value' : 'Decrypt Value', + label: state.fieldType === 'text' ? 'Encrypt Field' : 'Decrypt Field', leftSlot: , onSelect: () => handleFieldTypeChange(state.fieldType === 'text' ? 'encrypted' : 'text'), }, ], - [handleFieldTypeChange, isEncryptionEnabled, setState, state.fieldType, state.obscured], + [ + handleFieldTypeChange, + isEncryptionEnabled, + setState, + state.fieldType, + state.obscured, + state.value, + ], ); let tint: InputProps['tint']; diff --git a/src-web/components/core/PairEditor.tsx b/src-web/components/core/PairEditor.tsx index 7d4946541..56a7da2ec 100644 --- a/src-web/components/core/PairEditor.tsx +++ b/src-web/components/core/PairEditor.tsx @@ -41,6 +41,7 @@ export type PairEditorProps = { allowFileValues?: boolean; allowMultilineValues?: boolean; className?: string; + forcedEnvironmentId?: string; forceUpdateKey?: string; nameAutocomplete?: GenericCompletionConfig; nameAutocompleteFunctions?: boolean; @@ -81,6 +82,7 @@ export const PairEditor = forwardRef(function Pa allowFileValues, allowMultilineValues, className, + forcedEnvironmentId, forceUpdateKey, nameAutocomplete, nameAutocompleteFunctions, @@ -235,6 +237,7 @@ export const PairEditor = forwardRef(function Pa allowFileValues={allowFileValues} allowMultilineValues={allowMultilineValues} className="py-1" + forcedEnvironmentId={forcedEnvironmentId} forceFocusNamePairId={forceFocusNamePairId} forceFocusValuePairId={forceFocusValuePairId} forceUpdateKey={forceUpdateKey} @@ -292,6 +295,7 @@ type PairEditorRowProps = { PairEditorProps, | 'allowFileValues' | 'allowMultilineValues' + | 'forcedEnvironmentId' | 'forceUpdateKey' | 'nameAutocomplete' | 'nameAutocompleteVariables' @@ -311,6 +315,7 @@ function PairEditorRow({ allowFileValues, allowMultilineValues, className, + forcedEnvironmentId, forceFocusNamePairId, forceFocusValuePairId, forceUpdateKey, @@ -502,6 +507,7 @@ function PairEditorRow({ size="sm" required={!isLast && !!pair.enabled && !!pair.value} validate={nameValidate} + forcedEnvironmentId={forcedEnvironmentId} forceUpdateKey={forceUpdateKey} containerClassName={classNames(isLast && 'border-dashed')} defaultValue={pair.name} @@ -549,6 +555,7 @@ function PairEditorRow({ size="sm" containerClassName={classNames(isLast && 'border-dashed')} validate={valueValidate} + forcedEnvironmentId={forcedEnvironmentId} forceUpdateKey={forceUpdateKey} defaultValue={pair.value} label="Value" diff --git a/src-web/components/core/PairOrBulkEditor.tsx b/src-web/components/core/PairOrBulkEditor.tsx index 05e864ec9..be3c83cfe 100644 --- a/src-web/components/core/PairOrBulkEditor.tsx +++ b/src-web/components/core/PairOrBulkEditor.tsx @@ -8,6 +8,7 @@ import { PairEditor } from './PairEditor'; interface Props extends PairEditorProps { preferenceName: string; + forcedEnvironmentId?: string; } export const PairOrBulkEditor = forwardRef(function PairOrBulkEditor( diff --git a/src-web/components/core/Tooltip.tsx b/src-web/components/core/Tooltip.tsx index ec96ea8bc..1702c00bf 100644 --- a/src-web/components/core/Tooltip.tsx +++ b/src-web/components/core/Tooltip.tsx @@ -7,6 +7,7 @@ import { Portal } from '../Portal'; export interface TooltipProps { children: ReactNode; content: ReactNode; + tabIndex?: number, size?: 'md' | 'lg'; } @@ -18,7 +19,7 @@ const hiddenStyles: CSSProperties = { opacity: 0, }; -export function Tooltip({ children, content, size = 'md' }: TooltipProps) { +export function Tooltip({ children, content, tabIndex, size = 'md' }: TooltipProps) { const [isOpen, setIsOpen] = useState(); const triggerRef = useRef(null); const tooltipRef = useRef(null); @@ -89,11 +90,12 @@ export function Tooltip({ children, content, size = 'md' }: TooltipProps) {
- + ); } diff --git a/src-web/hooks/useActiveEnvironmentVariables.ts b/src-web/hooks/useActiveEnvironmentVariables.ts index 8f8632f27..a13ca905d 100644 --- a/src-web/hooks/useActiveEnvironmentVariables.ts +++ b/src-web/hooks/useActiveEnvironmentVariables.ts @@ -1,24 +1,8 @@ -import type { EnvironmentVariable } from '@yaakapp-internal/models'; import { useAtomValue } from 'jotai'; -import { useMemo } from 'react'; import { activeEnvironmentAtom } from './useActiveEnvironment'; -import { useEnvironmentsBreakdown } from './useEnvironmentsBreakdown'; +import { useEnvironmentVariables } from './useEnvironmentVariables'; export function useActiveEnvironmentVariables() { - const { baseEnvironment } = useEnvironmentsBreakdown(); const activeEnvironment = useAtomValue(activeEnvironmentAtom); - return useMemo(() => { - const varMap: Record = {}; - const allVariables = [ - ...(baseEnvironment?.variables ?? []), - ...(activeEnvironment?.variables ?? []), - ]; - - for (const v of allVariables) { - if (!v.enabled || !v.name) continue; - varMap[v.name] = v; - } - - return Object.values(varMap); - }, [activeEnvironment, baseEnvironment]); + return useEnvironmentVariables(activeEnvironment?.id ?? null); } diff --git a/src-web/hooks/useCopy.ts b/src-web/hooks/useCopy.ts deleted file mode 100644 index e648a5bf9..000000000 --- a/src-web/hooks/useCopy.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { clear, writeText } from '@tauri-apps/plugin-clipboard-manager'; -import { useCallback } from 'react'; -import { showToast } from '../lib/toast'; - -export function useCopy({ disableToast }: { disableToast?: boolean } = {}) { - const copy = useCallback( - (text: string | null) => { - if (text == null) { - clear().catch(console.error); - } else { - writeText(text).catch(console.error); - } - if (text != '' && !disableToast) { - showToast({ - id: 'copied', - color: 'success', - icon: 'copy', - message: 'Copied to clipboard', - }); - } - }, - [disableToast], - ); - - return copy; -} diff --git a/src-web/hooks/useCopyHttpResponse.ts b/src-web/hooks/useCopyHttpResponse.ts index c5a5017ff..390981765 100644 --- a/src-web/hooks/useCopyHttpResponse.ts +++ b/src-web/hooks/useCopyHttpResponse.ts @@ -1,15 +1,14 @@ -import { useFastMutation } from './useFastMutation'; import type { HttpResponse } from '@yaakapp-internal/models'; -import { useCopy } from './useCopy'; +import { copyToClipboard } from '../lib/copy'; import { getResponseBodyText } from '../lib/responseBody'; +import { useFastMutation } from './useFastMutation'; export function useCopyHttpResponse(response: HttpResponse) { - const copy = useCopy(); return useFastMutation({ mutationKey: ['copy_http_response', response.id], async mutationFn() { const body = await getResponseBodyText(response); - copy(body); + copyToClipboard(body); }, }); } diff --git a/src-web/hooks/useCreateEnvironment.ts b/src-web/hooks/useCreateEnvironment.ts index e03904eae..34f4a923b 100644 --- a/src-web/hooks/useCreateEnvironment.ts +++ b/src-web/hooks/useCreateEnvironment.ts @@ -1,20 +1,21 @@ import type { Environment } from '@yaakapp-internal/models'; import { createWorkspaceModel } from '@yaakapp-internal/models'; -import { jotaiStore } from '../lib/jotai'; +import { useAtomValue } from 'jotai'; import { showPrompt } from '../lib/prompt'; import { setWorkspaceSearchParams } from '../lib/setWorkspaceSearchParams'; import { activeWorkspaceIdAtom } from './useActiveWorkspace'; import { useFastMutation } from './useFastMutation'; export function useCreateEnvironment() { - return useFastMutation({ - mutationKey: ['create_environment'], + const workspaceId = useAtomValue(activeWorkspaceIdAtom); + + return useFastMutation({ + mutationKey: ['create_environment', workspaceId], mutationFn: async (baseEnvironment) => { if (baseEnvironment == null) { throw new Error('No base environment passed'); } - const workspaceId = jotaiStore.get(activeWorkspaceIdAtom); if (workspaceId == null) { throw new Error('Cannot create environment when no active workspace'); } @@ -28,17 +29,21 @@ export function useCreateEnvironment() { defaultValue: 'My Environment', confirmText: 'Create', }); - if (name == null) throw new Error('No name provided to create environment'); + if (name == null) return null; return createWorkspaceModel({ model: 'environment', name, variables: [], workspaceId, - environmentId: baseEnvironment.id, + base: false, }); }, onSuccess: async (environmentId) => { + if (environmentId == null) { + return; // Was not created + } + setWorkspaceSearchParams({ environment_id: environmentId }); }, }); diff --git a/src-web/hooks/useEnvironmentVariables.ts b/src-web/hooks/useEnvironmentVariables.ts new file mode 100644 index 000000000..424176eb7 --- /dev/null +++ b/src-web/hooks/useEnvironmentVariables.ts @@ -0,0 +1,25 @@ +import type { EnvironmentVariable } from '@yaakapp-internal/models'; +import { environmentsAtom } from '@yaakapp-internal/models'; +import { useAtomValue } from 'jotai'; +import { useMemo } from 'react'; +import { useEnvironmentsBreakdown } from './useEnvironmentsBreakdown'; + +export function useEnvironmentVariables(environmentId: string | null) { + const { baseEnvironment } = useEnvironmentsBreakdown(); + const activeEnvironment = + useAtomValue(environmentsAtom).find((e) => e.id === environmentId) ?? null; + return useMemo(() => { + const varMap: Record = {}; + const allVariables = [ + ...(baseEnvironment?.variables ?? []), + ...(activeEnvironment?.variables ?? []), + ]; + + for (const v of allVariables) { + if (!v.enabled || !v.name) continue; + varMap[v.name] = v; + } + + return Object.values(varMap); + }, [activeEnvironment, baseEnvironment]); +} diff --git a/src-web/hooks/useEnvironmentsBreakdown.ts b/src-web/hooks/useEnvironmentsBreakdown.ts index a2df647c6..dea73621c 100644 --- a/src-web/hooks/useEnvironmentsBreakdown.ts +++ b/src-web/hooks/useEnvironmentsBreakdown.ts @@ -5,9 +5,12 @@ import { useMemo } from 'react'; export function useEnvironmentsBreakdown() { const allEnvironments = useAtomValue(environmentsAtom); return useMemo(() => { - const baseEnvironment = allEnvironments.find((e) => e.environmentId == null) ?? null; - const subEnvironments = - allEnvironments.filter((e) => e.environmentId === (baseEnvironment?.id ?? 'n/a')) ?? []; - return { allEnvironments, baseEnvironment, subEnvironments }; + const baseEnvironments = allEnvironments.filter((e) => e.base) ?? []; + const subEnvironments = allEnvironments.filter((e) => !e.base) ?? []; + + const baseEnvironment = baseEnvironments[0] ?? null; + const otherBaseEnvironments = + baseEnvironments.filter((e) => e.id !== baseEnvironment?.id) ?? []; + return { allEnvironments, baseEnvironment, subEnvironments, otherBaseEnvironments }; }, [allEnvironments]); } diff --git a/src-web/hooks/useGenerateThemeCss.ts b/src-web/hooks/useGenerateThemeCss.ts index 5484c0183..1cd0f03bd 100644 --- a/src-web/hooks/useGenerateThemeCss.ts +++ b/src-web/hooks/useGenerateThemeCss.ts @@ -1,3 +1,4 @@ +import { copyToClipboard } from '../lib/copy'; import { catppuccinMacchiato } from '../lib/theme/themes/catppuccin'; import { githubLight } from '../lib/theme/themes/github'; import { gruvboxDefault } from '../lib/theme/themes/gruvbox'; @@ -6,11 +7,9 @@ import { monokaiProDefault } from '../lib/theme/themes/monokai-pro'; import { rosePineDefault } from '../lib/theme/themes/rose-pine'; import { yaakDark } from '../lib/theme/themes/yaak'; import { getThemeCSS } from '../lib/theme/window'; -import { useCopy } from './useCopy'; import { useListenToTauriEvent } from './useListenToTauriEvent'; export function useGenerateThemeCss() { - const copy = useCopy(); useListenToTauriEvent('generate_theme_css', () => { const themesCss = [ yaakDark, @@ -23,6 +22,6 @@ export function useGenerateThemeCss() { ] .map(getThemeCSS) .join('\n\n'); - copy(themesCss); + copyToClipboard(themesCss); }); } diff --git a/src-web/hooks/usePinnedWebsocketConnection.ts b/src-web/hooks/usePinnedWebsocketConnection.ts index 76a606c8d..698d90273 100644 --- a/src-web/hooks/usePinnedWebsocketConnection.ts +++ b/src-web/hooks/usePinnedWebsocketConnection.ts @@ -1,10 +1,6 @@ import { invoke } from '@tauri-apps/api/core'; import type { WebsocketConnection, WebsocketEvent } from '@yaakapp-internal/models'; -import { - replaceModelsInStore, - websocketConnectionsAtom, - websocketEventsAtom, -} from '@yaakapp-internal/models'; +import { replaceModelsInStore , websocketConnectionsAtom, websocketEventsAtom } from '@yaakapp-internal/models'; import { atom, useAtomValue } from 'jotai'; import { useEffect } from 'react'; import { atomWithKVStorage } from '../lib/atoms/atomWithKVStorage'; @@ -35,13 +31,6 @@ export const activeWebsocketConnectionAtom = atom((g return activeConnections.find((c) => c.id === pinnedConnectionId) ?? activeConnections[0] ?? null; }); -export const activeWebsocketEventsAtom = atom(async (get) => { - const connection = get(activeWebsocketConnectionAtom); - return invoke('plugin:yaak-models|websocket_events', { - connectionId: connection?.id ?? 'n/a', - }); -}); - export function setPinnedWebsocketConnectionId(id: string | null) { const activeRequestId = jotaiStore.get(activeRequestIdAtom); const activeConnections = jotaiStore.get(activeWebsocketConnectionsAtom); diff --git a/src-web/init/sync.ts b/src-web/init/sync.ts index 3e45e845e..6098625c6 100644 --- a/src-web/init/sync.ts +++ b/src-web/init/sync.ts @@ -68,7 +68,7 @@ function isModelRelevant(m: AnyModel) { if ( m.model !== 'workspace' && m.model !== 'folder' && - // m.model !== 'environment' && // Not synced anymore + m.model !== 'environment' && m.model !== 'http_request' && m.model !== 'grpc_request' && m.model !== 'websocket_request' diff --git a/src-web/lib/copy.ts b/src-web/lib/copy.ts new file mode 100644 index 000000000..f7bc78781 --- /dev/null +++ b/src-web/lib/copy.ts @@ -0,0 +1,22 @@ +import { clear, writeText } from '@tauri-apps/plugin-clipboard-manager'; +import { showToast } from './toast'; + +export function copyToClipboard( + text: string | null, + { disableToast }: { disableToast?: boolean } = {}, +) { + if (text == null) { + clear().catch(console.error); + } else { + writeText(text).catch(console.error); + } + + if (text != '' && !disableToast) { + showToast({ + id: 'copied', + color: 'success', + icon: 'copy', + message: 'Copied to clipboard', + }); + } +} From a5333deb712184a1579c83216b76bb96f636393a Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 8 May 2025 14:28:41 -0700 Subject: [PATCH 157/996] Logic for new Environment.base field --- package-lock.json | 20 ++++++++++--------- package.json | 2 +- plugins/importer-insomnia/src/index.ts | 2 +- .../tests/fixtures/basic.output.json | 6 +++--- plugins/importer-yaak/src/index.ts | 10 +++++++++- plugins/importer-yaak/tests/index.test.ts | 2 +- plugins/template-function-file/package.json | 9 --------- plugins/template-function-file/src/index.ts | 18 ----------------- 8 files changed, 26 insertions(+), 43 deletions(-) delete mode 100644 plugins/template-function-file/package.json delete mode 100644 plugins/template-function-file/src/index.ts diff --git a/package-lock.json b/package-lock.json index de4cca535..7dfa923fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.5.0" + "@yaakapp/api": "^0.5.1" }, "devDependencies": { "@types/node": "^22.7.4", @@ -999,9 +999,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.5.0.tgz", - "integrity": "sha512-M0PPLGWQft+eQOOJ7ubwvRm3LTYXjAWQ8nniiqV3TkRcwa5++PteIH0OHV2L3Pei8cRQA8S25AD+RajyvFC8XQ==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.5.1.tgz", + "integrity": "sha512-0YFrrTJVjrnsSm9BTxSnz1pd1+Q52/CBV1QpTVtXPPqlSIwcvj7jMdwuDpSKy5G8xbaoVzTgBnW25RgKog/q7g==", "dependencies": { "@types/node": "^22.5.4" } @@ -1054,10 +1054,6 @@ "resolved": "plugins/importer-yaak", "link": true }, - "node_modules/@yaakapp/template-function-file": { - "resolved": "plugins/template-function-file", - "link": true - }, "node_modules/@yaakapp/template-function-fs": { "resolved": "plugins/template-function-fs", "link": true @@ -7196,7 +7192,8 @@ }, "plugins/template-function-file": { "name": "@yaakapp/template-function-file", - "version": "0.0.1" + "version": "0.0.1", + "extraneous": true }, "plugins/template-function-fs": { "name": "@yaakapp/template-function-fs", @@ -7225,6 +7222,11 @@ "devDependencies": { "@types/jsonpath": "^0.2.4" } + }, + "plugins/template-function-secure": { + "name": "@yaakapp/template-function-secure", + "version": "0.0.1", + "extraneous": true } } } diff --git a/package.json b/package.json index ef57489af..1e60d96c2 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.5.0" + "@yaakapp/api": "^0.5.1" } } diff --git a/plugins/importer-insomnia/src/index.ts b/plugins/importer-insomnia/src/index.ts index d4e04b0a7..e589365a4 100644 --- a/plugins/importer-insomnia/src/index.ts +++ b/plugins/importer-insomnia/src/index.ts @@ -101,7 +101,7 @@ function importEnvironment(e: any, workspaceId: string): ExportResources['enviro createdAt: e.created ? new Date(e.created).toISOString().replace('Z', '') : undefined, updatedAt: e.updated ? new Date(e.updated).toISOString().replace('Z', '') : undefined, workspaceId: convertId(workspaceId), - environmentId: e.parentId === workspaceId ? null : convertId(e.parentId), + base: e.parentId === workspaceId, model: 'environment', name: e.name, variables: Object.entries(e.data).map(([name, value]) => ({ diff --git a/plugins/importer-insomnia/tests/fixtures/basic.output.json b/plugins/importer-insomnia/tests/fixtures/basic.output.json index f989ec0e8..c1381750c 100644 --- a/plugins/importer-insomnia/tests/fixtures/basic.output.json +++ b/plugins/importer-insomnia/tests/fixtures/basic.output.json @@ -3,7 +3,7 @@ "environments": [ { "createdAt": "2025-01-13T15:15:43.767", - "environmentId": null, + "base": true, "id": "GENERATE_ID::env_16c0dec5b77c414ae0e419b8f10c3701300c5900", "model": "environment", "name": "Base Environment", @@ -18,7 +18,7 @@ }, { "createdAt": "2025-01-13T15:15:58.515", - "environmentId": "GENERATE_ID::env_16c0dec5b77c414ae0e419b8f10c3701300c5900", + "base": false, "id": "GENERATE_ID::env_799ae3d723ef44af91b4817e5d057e6d", "model": "environment", "name": "Production", @@ -33,7 +33,7 @@ }, { "createdAt": "2025-01-13T15:16:14.707", - "environmentId": "GENERATE_ID::env_16c0dec5b77c414ae0e419b8f10c3701300c5900", + "base": false, "id": "GENERATE_ID::env_030fbfdbb274426ebd78e2e6518f8553", "model": "environment", "name": "Staging", diff --git a/plugins/importer-yaak/src/index.ts b/plugins/importer-yaak/src/index.ts index d42953588..1a71cfbb5 100644 --- a/plugins/importer-yaak/src/index.ts +++ b/plugins/importer-yaak/src/index.ts @@ -46,7 +46,7 @@ export function migrateImport(contents: string) { parsed.resources.environments = parsed.resources.environments ?? []; parsed.resources.environments.push(baseEnvironment); - // Delete variables key from workspace + // Delete variables key from the workspace delete workspace.variables; // Add environmentId to relevant environments @@ -58,6 +58,14 @@ export function migrateImport(contents: string) { } } + // Migrate v3 to v4 + for (const environment of parsed.resources.environments ?? []) { + if ('environmentId' in environment) { + environment.base = environment.environmentId == null; + delete environment.environmentId; + } + } + return { resources: parsed.resources }; // Should already be in the correct format } diff --git a/plugins/importer-yaak/tests/index.test.ts b/plugins/importer-yaak/tests/index.test.ts index 533acd6e7..a55e62b17 100644 --- a/plugins/importer-yaak/tests/index.test.ts +++ b/plugins/importer-yaak/tests/index.test.ts @@ -53,7 +53,7 @@ describe('importer-yaak', () => { }], environments: [{ id: 'e_1', - environmentId: 'GENERATE_ID::base_env_w_1', + base: false, workspaceId: 'w_1', name: 'Production', variables: [{ name: 'E1', value: 'E1!' }], diff --git a/plugins/template-function-file/package.json b/plugins/template-function-file/package.json deleted file mode 100644 index 59aea7ab3..000000000 --- a/plugins/template-function-file/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@yaakapp/template-function-file", - "private": true, - "version": "0.0.1", - "scripts": { - "build": "yaakcli build ./src/index.ts", - "dev": "yaakcli dev ./src/index.js" - } -} diff --git a/plugins/template-function-file/src/index.ts b/plugins/template-function-file/src/index.ts deleted file mode 100644 index 472c1a0d9..000000000 --- a/plugins/template-function-file/src/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; -import fs from 'node:fs'; - -export const plugin: PluginDefinition = { - templateFunctions: [{ - name: 'fs.readFile', - args: [{ title: 'Select File', type: 'file', name: 'path', label: 'File' }], - async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { - if (!args.values.path) return null; - - try { - return fs.promises.readFile(args.values.path, 'utf-8'); - } catch (err) { - return null; - } - }, - }], -}; From 8be9c4c388036deeb44dcb95a6fe0ff8d2d6bdff Mon Sep 17 00:00:00 2001 From: mooonfly Date: Sun, 11 May 2025 21:22:36 +0800 Subject: [PATCH 158/996] fix curl import params (#6) --- plugins/importer-curl/src/index.ts | 34 ++++++++++++++++-------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts index 95a2b645e..887e4c1d9 100644 --- a/plugins/importer-curl/src/index.ts +++ b/plugins/importer-curl/src/index.ts @@ -386,22 +386,24 @@ function pairsToDataParameters(keyedPairs: FlagsByName): DataParameter[] { for (const p of pairs) { if (typeof p !== 'string') continue; - - const [name, value] = p.split('='); - if (p.startsWith('@')) { - // Yaak doesn't support files in url-encoded data, so - dataParameters.push({ - name: name ?? '', - value: '', - filePath: p.slice(1), - enabled: true, - }); - } else { - dataParameters.push({ - name: name ?? '', - value: flagName === 'data-urlencode' ? encodeURIComponent(value ?? '') : value ?? '', - enabled: true, - }); + let params = p.split("&"); + for (const param of params) { + const [name, value] = param.split('='); + if (param.startsWith('@')) { + // Yaak doesn't support files in url-encoded data, so + dataParameters.push({ + name: name ?? '', + value: '', + filePath: param.slice(1), + enabled: true, + }); + } else { + dataParameters.push({ + name: name ?? '', + value: flagName === 'data-urlencode' ? encodeURIComponent(value ?? '') : value ?? '', + enabled: true, + }); + } } } } From 20b0b4fb69a6a4d99f5ff2590726d23e733a7b07 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 11 May 2025 06:31:21 -0700 Subject: [PATCH 159/996] Add test --- plugins/importer-curl/tests/index.test.ts | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/plugins/importer-curl/tests/index.test.ts b/plugins/importer-curl/tests/index.test.ts index 81669fd27..10c266fa0 100644 --- a/plugins/importer-curl/tests/index.test.ts +++ b/plugins/importer-curl/tests/index.test.ts @@ -172,6 +172,35 @@ describe('importer-curl', () => { }); }); + test('Imports combined data params as form url-encoded', () => { + expect(convertCurl(`curl -d 'a=aaa&b=bbb&c' https://yaak.app`)).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + method: 'POST', + url: 'https://yaak.app', + bodyType: 'application/x-www-form-urlencoded', + headers: [ + { + name: 'Content-Type', + value: 'application/x-www-form-urlencoded', + enabled: true, + }, + ], + body: { + form: [ + { name: 'a', value: 'aaa', enabled: true }, + { name: 'b', value: 'bbb', enabled: true }, + { name: 'c', value: '', enabled: true }, + ], + }, + }), + ], + }, + }); + }); + test('Imports data params as text', () => { expect( convertCurl('curl -H Content-Type:text/plain -d a -d b -d c=ccc https://yaak.app'), From 84b8d130dcd729bf2864ac9479ea30d204d9fedd Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 11 May 2025 06:36:50 -0700 Subject: [PATCH 160/996] Some small tweaks for plugins --- packages/plugin-runtime-types/package.json | 2 +- .../src/bindings/gen_models.ts | 2 +- packages/plugin-runtime-types/src/index.ts | 4 +++ .../src/plugins/Context.ts | 2 +- .../src/plugins/FilterPlugin.ts | 2 +- .../src/plugins/ImporterPlugin.ts | 26 ++++++++++++------- src-web/components/EnvironmentEditDialog.tsx | 6 ++++- 7 files changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/plugin-runtime-types/package.json b/packages/plugin-runtime-types/package.json index 5b6ee95f7..7c6fb290d 100644 --- a/packages/plugin-runtime-types/package.json +++ b/packages/plugin-runtime-types/package.json @@ -1,6 +1,6 @@ { "name": "@yaakapp/api", - "version": "0.5.0", + "version": "0.5.3", "main": "lib/index.js", "typings": "./lib/index.d.ts", "files": [ diff --git a/packages/plugin-runtime-types/src/bindings/gen_models.ts b/packages/plugin-runtime-types/src/bindings/gen_models.ts index 4b5e5ad2f..a9e7794c9 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_models.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_models.ts @@ -1,6 +1,6 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type Environment = { model: "environment", id: string, workspaceId: string, environmentId: string | null, createdAt: string, updatedAt: string, name: string, variables: Array, }; +export type Environment = { model: "environment", id: string, workspaceId: string, createdAt: string, updatedAt: string, name: string, public: boolean, base: boolean, variables: Array, }; export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id?: string, }; diff --git a/packages/plugin-runtime-types/src/index.ts b/packages/plugin-runtime-types/src/index.ts index 3f19e322a..143139638 100644 --- a/packages/plugin-runtime-types/src/index.ts +++ b/packages/plugin-runtime-types/src/index.ts @@ -3,3 +3,7 @@ export type * from './themes'; export * from './bindings/gen_models'; export * from './bindings/gen_events'; + +// Some extras for utility + +export type { PartialImportResources } from './plugins/ImporterPlugin'; diff --git a/packages/plugin-runtime-types/src/plugins/Context.ts b/packages/plugin-runtime-types/src/plugins/Context.ts index 15715c650..f55a38700 100644 --- a/packages/plugin-runtime-types/src/plugins/Context.ts +++ b/packages/plugin-runtime-types/src/plugins/Context.ts @@ -34,7 +34,7 @@ export interface Context { openUrl( args: OpenWindowRequest & { onNavigate?: (args: { url: string }) => void; - onClose: () => void; + onClose?: () => void; }, ): Promise<{ close: () => void }>; }; diff --git a/packages/plugin-runtime-types/src/plugins/FilterPlugin.ts b/packages/plugin-runtime-types/src/plugins/FilterPlugin.ts index 57a1af073..b7ebf5817 100644 --- a/packages/plugin-runtime-types/src/plugins/FilterPlugin.ts +++ b/packages/plugin-runtime-types/src/plugins/FilterPlugin.ts @@ -1,6 +1,6 @@ import type { Context } from './Context'; -export type FilterPluginResponse = { filtered: string }; +type FilterPluginResponse = { filtered: string }; export type FilterPlugin = { name: string; diff --git a/packages/plugin-runtime-types/src/plugins/ImporterPlugin.ts b/packages/plugin-runtime-types/src/plugins/ImporterPlugin.ts index 309f8cdab..f2ccff9be 100644 --- a/packages/plugin-runtime-types/src/plugins/ImporterPlugin.ts +++ b/packages/plugin-runtime-types/src/plugins/ImporterPlugin.ts @@ -1,15 +1,21 @@ -import { Environment, Folder, GrpcRequest, HttpRequest, Workspace } from '../bindings/gen_models'; -import type { AtLeast } from '../helpers'; +import { ImportResources } from '../bindings/gen_events'; +import { AtLeast } from '../helpers'; import type { Context } from './Context'; -type ImportPluginResponse = null | { - resources: { - workspaces: AtLeast[]; - environments: AtLeast[]; - folders: AtLeast[]; - httpRequests: AtLeast[]; - grpcRequests: AtLeast[]; - }; +type RootFields = 'name' | 'id' | 'model'; +type CommonFields = RootFields | 'workspaceId'; + +export type PartialImportResources = { + workspaces: Array>; + environments: Array>; + folders: Array>; + httpRequests: Array>; + grpcRequests: Array>; + websocketRequests: Array>; +}; + +export type ImportPluginResponse = null | { + resources: PartialImportResources; }; export type ImporterPlugin = { diff --git a/src-web/components/EnvironmentEditDialog.tsx b/src-web/components/EnvironmentEditDialog.tsx index f42ed7d68..d9bccdfed 100644 --- a/src-web/components/EnvironmentEditDialog.tsx +++ b/src-web/components/EnvironmentEditDialog.tsx @@ -258,7 +258,11 @@ const EnvironmentEditor = function ({ )} {activeEnvironment.public && promptToEncrypt && ( - + This environment is sharable. Ensure variable values are encrypted to avoid accidental leaking of secrets during directory sync or data export. From 8c0f889dd2edf77f5d820473381d82005788b1e8 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 11 May 2025 06:44:54 -0700 Subject: [PATCH 161/996] Insomnia v5 importer (#7) Add support for the new Insomnia 5 export format --- package-lock.json | 8 +- package.json | 2 +- plugins/importer-insomnia/src/common.ts | 34 +++ plugins/importer-insomnia/src/index.ts | 274 +----------------- plugins/importer-insomnia/src/v4.ts | 206 +++++++++++++ plugins/importer-insomnia/src/v5.ts | 265 +++++++++++++++++ .../tests/fixtures/basic.output.json | 10 +- .../tests/fixtures/version-5.input.yaml | 142 +++++++++ .../tests/fixtures/version-5.output.json | 172 +++++++++++ plugins/importer-insomnia/tests/index.test.ts | 13 +- 10 files changed, 853 insertions(+), 273 deletions(-) create mode 100644 plugins/importer-insomnia/src/common.ts create mode 100644 plugins/importer-insomnia/src/v4.ts create mode 100644 plugins/importer-insomnia/src/v5.ts create mode 100644 plugins/importer-insomnia/tests/fixtures/version-5.input.yaml create mode 100644 plugins/importer-insomnia/tests/fixtures/version-5.output.json diff --git a/package-lock.json b/package-lock.json index 7dfa923fe..7e558688a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.5.1" + "@yaakapp/api": "^0.5.3" }, "devDependencies": { "@types/node": "^22.7.4", @@ -999,9 +999,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.5.1.tgz", - "integrity": "sha512-0YFrrTJVjrnsSm9BTxSnz1pd1+Q52/CBV1QpTVtXPPqlSIwcvj7jMdwuDpSKy5G8xbaoVzTgBnW25RgKog/q7g==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.5.3.tgz", + "integrity": "sha512-JKO0t5H+wM2KWpNgiNW5UVmk66c7p2WFCHa8TnLwnkFpub/3ktZfMY1Y+c21N2gsurqUe3wmcNRM0J1nQrR9rA==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/package.json b/package.json index 1e60d96c2..882533abe 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.5.1" + "@yaakapp/api": "^0.5.3" } } diff --git a/plugins/importer-insomnia/src/common.ts b/plugins/importer-insomnia/src/common.ts new file mode 100644 index 000000000..253924f0d --- /dev/null +++ b/plugins/importer-insomnia/src/common.ts @@ -0,0 +1,34 @@ + +export function convertSyntax(variable: string): string { + if (!isJSString(variable)) return variable; + return variable.replaceAll(/{{\s*(_\.)?([^}]+)\s*}}/g, '${[$2]}'); +} + +export function isJSObject(obj: any) { + return Object.prototype.toString.call(obj) === '[object Object]'; +} + +export function isJSString(obj: any) { + return Object.prototype.toString.call(obj) === '[object String]'; +} + +export function convertId(id: string): string { + if (id.startsWith('GENERATE_ID::')) { + return id; + } + return `GENERATE_ID::${id}`; +} + +export function deleteUndefinedAttrs(obj: T): T { + if (Array.isArray(obj) && obj != null) { + return obj.map(deleteUndefinedAttrs) as T; + } else if (typeof obj === 'object' && obj != null) { + return Object.fromEntries( + Object.entries(obj) + .filter(([, v]) => v !== undefined) + .map(([k, v]) => [k, deleteUndefinedAttrs(v)]), + ) as T; + } else { + return obj; + } +} diff --git a/plugins/importer-insomnia/src/index.ts b/plugins/importer-insomnia/src/index.ts index e589365a4..4d95ac2bc 100644 --- a/plugins/importer-insomnia/src/index.ts +++ b/plugins/importer-insomnia/src/index.ts @@ -1,22 +1,15 @@ -import { Context, Environment, Folder, GrpcRequest, HttpRequest, PluginDefinition, Workspace } from '@yaakapp/api'; +import { Context, PluginDefinition } from '@yaakapp/api'; import YAML from 'yaml'; - -type AtLeast = Partial & Pick; - -export interface ExportResources { - workspaces: AtLeast[]; - environments: AtLeast[]; - httpRequests: AtLeast[]; - grpcRequests: AtLeast[]; - folders: AtLeast[]; -} +import { deleteUndefinedAttrs, isJSObject } from './common'; +import { convertInsomniaV4 } from './v4'; +import { convertInsomniaV5 } from './v5'; export const plugin: PluginDefinition = { importer: { name: 'Insomnia', description: 'Import Insomnia workspaces', - onImport(_ctx: Context, args: { text: string }) { - return convertInsomnia(args.text) as any; + async onImport(_ctx: Context, args: { text: string }) { + return convertInsomnia(args.text); }, }, }; @@ -34,258 +27,9 @@ export function convertInsomnia(contents: string) { } catch (e) { } - if (!isJSObject(parsed)) return; - if (!Array.isArray(parsed.resources)) return; - - const resources: ExportResources = { - workspaces: [], - httpRequests: [], - grpcRequests: [], - environments: [], - folders: [], - }; - - // Import workspaces - const workspacesToImport = parsed.resources.filter(isWorkspace); - for (const w of workspacesToImport) { - resources.workspaces.push({ - id: convertId(w._id), - createdAt: w.created ? new Date(w.created).toISOString().replace('Z', '') : undefined, - updatedAt: w.updated ? new Date(w.updated).toISOString().replace('Z', '') : undefined, - model: 'workspace', - name: w.name, - description: w.description || undefined, - }); - const environmentsToImport = parsed.resources.filter( - (r: any) => isEnvironment(r), - ); - resources.environments.push( - ...environmentsToImport.map((r: any) => importEnvironment(r, w._id)), - ); - - const nextFolder = (parentId: string) => { - const children = parsed.resources.filter((r: any) => r.parentId === parentId); - let sortPriority = 0; - for (const child of children) { - if (isRequestGroup(child)) { - resources.folders.push(importFolder(child, w._id)); - nextFolder(child._id); - } else if (isHttpRequest(child)) { - resources.httpRequests.push( - importHttpRequest(child, w._id, sortPriority++), - ); - } else if (isGrpcRequest(child)) { - resources.grpcRequests.push( - importGrpcRequest(child, w._id, sortPriority++), - ); - } - } - }; - - // Import folders - nextFolder(w._id); - } - - // Filter out any `null` values - resources.httpRequests = resources.httpRequests.filter(Boolean); - resources.grpcRequests = resources.grpcRequests.filter(Boolean); - resources.environments = resources.environments.filter(Boolean); - resources.workspaces = resources.workspaces.filter(Boolean); - - return { resources: deleteUndefinedAttrs(resources) }; -} - -function importEnvironment(e: any, workspaceId: string): ExportResources['environments'][0] { - return { - id: convertId(e._id), - createdAt: e.created ? new Date(e.created).toISOString().replace('Z', '') : undefined, - updatedAt: e.updated ? new Date(e.updated).toISOString().replace('Z', '') : undefined, - workspaceId: convertId(workspaceId), - base: e.parentId === workspaceId, - model: 'environment', - name: e.name, - variables: Object.entries(e.data).map(([name, value]) => ({ - enabled: true, - name, - value: `${value}`, - })), - }; -} - -function importFolder(f: any, workspaceId: string): ExportResources['folders'][0] { - return { - id: convertId(f._id), - createdAt: f.created ? new Date(f.created).toISOString().replace('Z', '') : undefined, - updatedAt: f.updated ? new Date(f.updated).toISOString().replace('Z', '') : undefined, - folderId: f.parentId === workspaceId ? null : convertId(f.parentId), - workspaceId: convertId(workspaceId), - description: f.description || undefined, - model: 'folder', - name: f.name, - }; -} - -function importGrpcRequest( - r: any, - workspaceId: string, - sortPriority = 0, -): ExportResources['grpcRequests'][0] { - const parts = r.protoMethodName.split('/').filter((p: any) => p !== ''); - const service = parts[0] ?? null; - const method = parts[1] ?? null; + if (!isJSObject(parsed)) return null; - return { - id: convertId(r._id), - createdAt: r.created ? new Date(r.created).toISOString().replace('Z', '') : undefined, - updatedAt: r.updated ? new Date(r.updated).toISOString().replace('Z', '') : undefined, - workspaceId: convertId(workspaceId), - folderId: r.parentId === workspaceId ? null : convertId(r.parentId), - model: 'grpc_request', - sortPriority, - name: r.name, - description: r.description || undefined, - url: convertSyntax(r.url), - service, - method, - message: r.body?.text ?? '', - metadata: (r.metadata ?? []) - .map((h: any) => ({ - enabled: !h.disabled, - name: h.name ?? '', - value: h.value ?? '', - })) - .filter(({ name, value }: any) => name !== '' || value !== ''), - }; -} + const result = convertInsomniaV5(parsed) ?? convertInsomniaV4(parsed); -function importHttpRequest( - r: any, - workspaceId: string, - sortPriority = 0, -): ExportResources['httpRequests'][0] { - let bodyType: string | null = null; - let body = {}; - if (r.body.mimeType === 'application/octet-stream') { - bodyType = 'binary'; - body = { filePath: r.body.fileName ?? '' }; - } else if (r.body?.mimeType === 'application/x-www-form-urlencoded') { - bodyType = 'application/x-www-form-urlencoded'; - body = { - form: (r.body.params ?? []).map((p: any) => ({ - enabled: !p.disabled, - name: p.name ?? '', - value: p.value ?? '', - })), - }; - } else if (r.body?.mimeType === 'multipart/form-data') { - bodyType = 'multipart/form-data'; - body = { - form: (r.body.params ?? []).map((p: any) => ({ - enabled: !p.disabled, - name: p.name ?? '', - value: p.value ?? '', - file: p.fileName ?? null, - })), - }; - } else if (r.body?.mimeType === 'application/graphql') { - bodyType = 'graphql'; - body = { text: convertSyntax(r.body.text ?? '') }; - } else if (r.body?.mimeType === 'application/json') { - bodyType = 'application/json'; - body = { text: convertSyntax(r.body.text ?? '') }; - } - - let authenticationType: string | null = null; - let authentication = {}; - if (r.authentication.type === 'bearer') { - authenticationType = 'bearer'; - authentication = { - token: convertSyntax(r.authentication.token), - }; - } else if (r.authentication.type === 'basic') { - authenticationType = 'basic'; - authentication = { - username: convertSyntax(r.authentication.username), - password: convertSyntax(r.authentication.password), - }; - } - - return { - id: convertId(r._id), - createdAt: r.created ? new Date(r.created).toISOString().replace('Z', '') : undefined, - updatedAt: r.updated ? new Date(r.updated).toISOString().replace('Z', '') : undefined, - workspaceId: convertId(workspaceId), - folderId: r.parentId === workspaceId ? null : convertId(r.parentId), - model: 'http_request', - sortPriority, - name: r.name, - description: r.description || undefined, - url: convertSyntax(r.url), - body, - bodyType, - authentication, - authenticationType, - method: r.method, - headers: (r.headers ?? []) - .map((h: any) => ({ - enabled: !h.disabled, - name: h.name ?? '', - value: h.value ?? '', - })) - .filter(({ name, value }: any) => name !== '' || value !== ''), - }; -} - -function convertSyntax(variable: string): string { - if (!isJSString(variable)) return variable; - return variable.replaceAll(/{{\s*(_\.)?([^}]+)\s*}}/g, '${[$2]}'); -} - -function isWorkspace(obj: any) { - return isJSObject(obj) && obj._type === 'workspace'; -} - -function isRequestGroup(obj: any) { - return isJSObject(obj) && obj._type === 'request_group'; -} - -function isHttpRequest(obj: any) { - return isJSObject(obj) && obj._type === 'request'; -} - -function isGrpcRequest(obj: any) { - return isJSObject(obj) && obj._type === 'grpc_request'; -} - -function isEnvironment(obj: any) { - return isJSObject(obj) && obj._type === 'environment'; -} - -function isJSObject(obj: any) { - return Object.prototype.toString.call(obj) === '[object Object]'; -} - -function isJSString(obj: any) { - return Object.prototype.toString.call(obj) === '[object String]'; -} - -function convertId(id: string): string { - if (id.startsWith('GENERATE_ID::')) { - return id; - } - return `GENERATE_ID::${id}`; -} - -function deleteUndefinedAttrs(obj: T): T { - if (Array.isArray(obj) && obj != null) { - return obj.map(deleteUndefinedAttrs) as T; - } else if (typeof obj === 'object' && obj != null) { - return Object.fromEntries( - Object.entries(obj) - .filter(([, v]) => v !== undefined) - .map(([k, v]) => [k, deleteUndefinedAttrs(v)]), - ) as T; - } else { - return obj; - } + return deleteUndefinedAttrs(result); } diff --git a/plugins/importer-insomnia/src/v4.ts b/plugins/importer-insomnia/src/v4.ts new file mode 100644 index 000000000..8fcb61731 --- /dev/null +++ b/plugins/importer-insomnia/src/v4.ts @@ -0,0 +1,206 @@ +import { PartialImportResources } from '@yaakapp/api'; +import { convertId, convertSyntax, isJSObject } from './common'; + +export function convertInsomniaV4(parsed: Record) { + if (!Array.isArray(parsed.resources)) return null; + + const resources: PartialImportResources = { + environments: [], + folders: [], + grpcRequests: [], + httpRequests: [], + websocketRequests: [], + workspaces: [], + }; + + // Import workspaces + const workspacesToImport = parsed.resources.filter(r => isJSObject(r) && r._type === 'workspace'); + for (const w of workspacesToImport) { + resources.workspaces.push({ + id: convertId(w._id), + createdAt: w.created ? new Date(w.created).toISOString().replace('Z', '') : undefined, + updatedAt: w.updated ? new Date(w.updated).toISOString().replace('Z', '') : undefined, + model: 'workspace', + name: w.name, + description: w.description || undefined, + }); + const environmentsToImport = parsed.resources.filter( + (r: any) => isJSObject(r) && r._type === 'environment', + ); + resources.environments.push( + ...environmentsToImport.map((r: any) => importEnvironment(r, w._id)), + ); + + const nextFolder = (parentId: string) => { + const children = parsed.resources.filter((r: any) => r.parentId === parentId); + for (const child of children) { + if (!isJSObject(child)) continue; + + if (child._type === 'request_group') { + resources.folders.push(importFolder(child, w._id)); + nextFolder(child._id); + } else if (child._type === 'request') { + resources.httpRequests.push( + importHttpRequest(child, w._id), + ); + } else if (child._type === 'grpc_request') { + resources.grpcRequests.push( + importGrpcRequest(child, w._id), + ); + } + } + }; + + // Import folders + nextFolder(w._id); + } + + // Filter out any `null` values + resources.httpRequests = resources.httpRequests.filter(Boolean); + resources.grpcRequests = resources.grpcRequests.filter(Boolean); + resources.environments = resources.environments.filter(Boolean); + resources.workspaces = resources.workspaces.filter(Boolean); + + return { resources }; +} + +function importHttpRequest( + r: any, + workspaceId: string, +): PartialImportResources['httpRequests'][0] { + let bodyType: string | null = null; + let body = {}; + if (r.body.mimeType === 'application/octet-stream') { + bodyType = 'binary'; + body = { filePath: r.body.fileName ?? '' }; + } else if (r.body?.mimeType === 'application/x-www-form-urlencoded') { + bodyType = 'application/x-www-form-urlencoded'; + body = { + form: (r.body.params ?? []).map((p: any) => ({ + enabled: !p.disabled, + name: p.name ?? '', + value: p.value ?? '', + })), + }; + } else if (r.body?.mimeType === 'multipart/form-data') { + bodyType = 'multipart/form-data'; + body = { + form: (r.body.params ?? []).map((p: any) => ({ + enabled: !p.disabled, + name: p.name ?? '', + value: p.value ?? '', + file: p.fileName ?? null, + })), + }; + } else if (r.body?.mimeType === 'application/graphql') { + bodyType = 'graphql'; + body = { text: convertSyntax(r.body.text ?? '') }; + } else if (r.body?.mimeType === 'application/json') { + bodyType = 'application/json'; + body = { text: convertSyntax(r.body.text ?? '') }; + } + + let authenticationType: string | null = null; + let authentication = {}; + if (r.authentication.type === 'bearer') { + authenticationType = 'bearer'; + authentication = { + token: convertSyntax(r.authentication.token), + }; + } else if (r.authentication.type === 'basic') { + authenticationType = 'basic'; + authentication = { + username: convertSyntax(r.authentication.username), + password: convertSyntax(r.authentication.password), + }; + } + + return { + id: convertId(r.meta?.id ?? r._id), + createdAt: r.created ? new Date(r.created).toISOString().replace('Z', '') : undefined, + updatedAt: r.modified ? new Date(r.modified).toISOString().replace('Z', '') : undefined, + workspaceId: convertId(workspaceId), + folderId: r.parentId === workspaceId ? null : convertId(r.parentId), + model: 'http_request', + sortPriority: r.metaSortKey, + name: r.name, + description: r.description || undefined, + url: convertSyntax(r.url), + body, + bodyType, + authentication, + authenticationType, + method: r.method, + headers: (r.headers ?? []) + .map((h: any) => ({ + enabled: !h.disabled, + name: h.name ?? '', + value: h.value ?? '', + })) + .filter(({ name, value }: any) => name !== '' || value !== ''), + }; +} + +function importGrpcRequest( + r: any, + workspaceId: string, +): PartialImportResources['grpcRequests'][0] { + const parts = r.protoMethodName.split('/').filter((p: any) => p !== ''); + const service = parts[0] ?? null; + const method = parts[1] ?? null; + + return { + id: convertId(r.meta?.id ?? r._id), + createdAt: r.created ? new Date(r.created).toISOString().replace('Z', '') : undefined, + updatedAt: r.modified ? new Date(r.modified).toISOString().replace('Z', '') : undefined, + workspaceId: convertId(workspaceId), + folderId: r.parentId === workspaceId ? null : convertId(r.parentId), + model: 'grpc_request', + sortPriority: r.metaSortKey, + name: r.name, + description: r.description || undefined, + url: convertSyntax(r.url), + service, + method, + message: r.body?.text ?? '', + metadata: (r.metadata ?? []) + .map((h: any) => ({ + enabled: !h.disabled, + name: h.name ?? '', + value: h.value ?? '', + })) + .filter(({ name, value }: any) => name !== '' || value !== ''), + }; +} + +function importFolder(f: any, workspaceId: string): PartialImportResources['folders'][0] { + return { + id: convertId(f._id), + createdAt: f.created ? new Date(f.created).toISOString().replace('Z', '') : undefined, + updatedAt: f.modified ? new Date(f.modified).toISOString().replace('Z', '') : undefined, + folderId: f.parentId === workspaceId ? null : convertId(f.parentId), + workspaceId: convertId(workspaceId), + description: f.description || undefined, + model: 'folder', + name: f.name, + }; +} + +function importEnvironment(e: any, workspaceId: string, isParent?: boolean): PartialImportResources['environments'][0] { + return { + id: convertId(e._id), + createdAt: e.created ? new Date(e.created).toISOString().replace('Z', '') : undefined, + updatedAt: e.modified ? new Date(e.modified).toISOString().replace('Z', '') : undefined, + workspaceId: convertId(workspaceId), + // @ts-ignore + sortPriority: e.metaSortKey, // Will be added to Yaak later + base: isParent ?? e.parentId === workspaceId, + model: 'environment', + name: e.name, + variables: Object.entries(e.data).map(([name, value]) => ({ + enabled: true, + name, + value: `${value}`, + })), + }; +} diff --git a/plugins/importer-insomnia/src/v5.ts b/plugins/importer-insomnia/src/v5.ts new file mode 100644 index 000000000..f85b9010f --- /dev/null +++ b/plugins/importer-insomnia/src/v5.ts @@ -0,0 +1,265 @@ +import { PartialImportResources } from '@yaakapp/api'; +import { convertId, convertSyntax, isJSObject } from './common'; + +export function convertInsomniaV5(parsed: Record) { + if (!Array.isArray(parsed.collection)) return null; + + const resources: PartialImportResources = { + environments: [], + folders: [], + grpcRequests: [], + httpRequests: [], + websocketRequests: [], + workspaces: [], + }; + + // Import workspaces + const meta: Record = parsed.meta ?? {}; + resources.workspaces.push({ + id: convertId(meta.id ?? 'collection'), + createdAt: meta.created ? new Date(meta.created).toISOString().replace('Z', '') : undefined, + updatedAt: meta.modified ? new Date(meta.modified).toISOString().replace('Z', '') : undefined, + model: 'workspace', + name: parsed.name, + description: meta.description || undefined, + }); + resources.environments.push( + importEnvironment(parsed.environments, meta.id, true), + ...(parsed.environments.subEnvironments ?? []).map((r: any) => importEnvironment(r, meta.id)), + ); + + const nextFolder = (children: any[], parentId: string) => { + for (const child of children ?? []) { + if (!isJSObject(child)) continue; + + if (Array.isArray(child.children)) { + resources.folders.push(importFolder(child, meta.id, parentId)); + nextFolder(child.children, child.meta.id); + } else if (child.method) { + resources.httpRequests.push( + importHttpRequest(child, meta.id, parentId), + ); + } else if (child.protoFileId) { + resources.grpcRequests.push( + importGrpcRequest(child, meta.id, parentId), + ); + } else if (child.url) { + resources.websocketRequests.push( + importWebsocketRequest(child, meta.id, parentId), + ); + } + } + }; + + // Import folders + nextFolder(parsed.collection ?? [], meta.id); + + // Filter out any `null` values + resources.httpRequests = resources.httpRequests.filter(Boolean); + resources.grpcRequests = resources.grpcRequests.filter(Boolean); + resources.environments = resources.environments.filter(Boolean); + resources.workspaces = resources.workspaces.filter(Boolean); + + return { resources }; +} + +function importHttpRequest( + r: any, + workspaceId: string, + parentId: string, +): PartialImportResources['httpRequests'][0] { + const id = r.meta?.id ?? r._id; + const created = r.meta?.created ?? r.created; + const updated = r.meta?.modified ?? r.updated; + const sortKey = r.meta?.sortKey ?? r.sortKey; + + let bodyType: string | null = null; + let body = {}; + if (r.body.mimeType === 'application/octet-stream') { + bodyType = 'binary'; + body = { filePath: r.body.fileName ?? '' }; + } else if (r.body?.mimeType === 'application/x-www-form-urlencoded') { + bodyType = 'application/x-www-form-urlencoded'; + body = { + form: (r.body.params ?? []).map((p: any) => ({ + enabled: !p.disabled, + name: p.name ?? '', + value: p.value ?? '', + })), + }; + } else if (r.body?.mimeType === 'multipart/form-data') { + bodyType = 'multipart/form-data'; + body = { + form: (r.body.params ?? []).map((p: any) => ({ + enabled: !p.disabled, + name: p.name ?? '', + value: p.value ?? '', + file: p.fileName ?? null, + })), + }; + } else if (r.body?.mimeType === 'application/graphql') { + bodyType = 'graphql'; + body = { text: convertSyntax(r.body.text ?? '') }; + } else if (r.body?.mimeType === 'application/json') { + bodyType = 'application/json'; + body = { text: convertSyntax(r.body.text ?? '') }; + } + + return { + id: convertId(id), + workspaceId: convertId(workspaceId), + createdAt: created ? new Date(created).toISOString().replace('Z', '') : undefined, + updatedAt: updated ? new Date(updated).toISOString().replace('Z', '') : undefined, + folderId: parentId === workspaceId ? null : convertId(parentId), + sortPriority: sortKey, + model: 'http_request', + name: r.name, + description: r.meta?.description || undefined, + url: convertSyntax(r.url), + body, + bodyType, + method: r.method, + ...importHeaders(r), + ...importAuthentication(r), + }; +} + +function importGrpcRequest( + r: any, + workspaceId: string, + parentId: string, +): PartialImportResources['grpcRequests'][0] { + const id = r.meta?.id ?? r._id; + const created = r.meta?.created ?? r.created; + const updated = r.meta?.modified ?? r.updated; + const sortKey = r.meta?.sortKey ?? r.sortKey; + + const parts = r.protoMethodName.split('/').filter((p: any) => p !== ''); + const service = parts[0] ?? null; + const method = parts[1] ?? null; + + return { + model: 'grpc_request', + id: convertId(id), + workspaceId: convertId(workspaceId), + createdAt: created ? new Date(created).toISOString().replace('Z', '') : undefined, + updatedAt: updated ? new Date(updated).toISOString().replace('Z', '') : undefined, + folderId: parentId === workspaceId ? null : convertId(parentId), + sortPriority: sortKey, + name: r.name, + description: r.description || undefined, + url: convertSyntax(r.url), + service, + method, + message: r.body?.text ?? '', + metadata: (r.metadata ?? []) + .map((h: any) => ({ + enabled: !h.disabled, + name: h.name ?? '', + value: h.value ?? '', + })) + .filter(({ name, value }: any) => name !== '' || value !== ''), + }; +} + +function importWebsocketRequest( + r: any, + workspaceId: string, + parentId: string, +): PartialImportResources['websocketRequests'][0] { + const id = r.meta?.id ?? r._id; + const created = r.meta?.created ?? r.created; + const updated = r.meta?.modified ?? r.updated; + const sortKey = r.meta?.sortKey ?? r.sortKey; + + return { + model: 'websocket_request', + id: convertId(id), + workspaceId: convertId(workspaceId), + createdAt: created ? new Date(created).toISOString().replace('Z', '') : undefined, + updatedAt: updated ? new Date(updated).toISOString().replace('Z', '') : undefined, + folderId: parentId === workspaceId ? null : convertId(parentId), + sortPriority: sortKey, + name: r.name, + description: r.description || undefined, + url: convertSyntax(r.url), + message: r.body?.text ?? '', + ...importHeaders(r), + ...importAuthentication(r), + }; +} + +function importHeaders(r: any) { + const headers = (r.headers ?? []) + .map((h: any) => ({ + enabled: !h.disabled, + name: h.name ?? '', + value: h.value ?? '', + })) + .filter(({ name, value }: any) => name !== '' || value !== ''); + return { headers } as const; +} + +function importAuthentication(r: any) { + let authenticationType: string | null = null; + let authentication = {}; + if (r.authentication?.type === 'bearer') { + authenticationType = 'bearer'; + authentication = { + token: convertSyntax(r.authentication.token), + }; + } else if (r.authentication?.type === 'basic') { + authenticationType = 'basic'; + authentication = { + username: convertSyntax(r.authentication.username), + password: convertSyntax(r.authentication.password), + }; + } + + return { authenticationType, authentication } as const; +} + +function importFolder(f: any, workspaceId: string, parentId: string): PartialImportResources['folders'][0] { + const id = f.meta?.id ?? f._id; + const created = f.meta?.created ?? f.created; + const updated = f.meta?.modified ?? f.updated; + const sortKey = f.meta?.sortKey ?? f.sortKey; + + return { + model: 'folder', + id: convertId(id), + createdAt: created ? new Date(created).toISOString().replace('Z', '') : undefined, + updatedAt: updated ? new Date(updated).toISOString().replace('Z', '') : undefined, + folderId: parentId === workspaceId ? null : convertId(parentId), + sortPriority: sortKey, + workspaceId: convertId(workspaceId), + description: f.description || undefined, + name: f.name, + }; +} + + +function importEnvironment(e: any, workspaceId: string, isParent?: boolean): PartialImportResources['environments'][0] { + const id = e.meta?.id ?? e._id; + const created = e.meta?.created ?? e.created; + const updated = e.meta?.modified ?? e.updated; + const sortKey = e.meta?.sortKey ?? e.sortKey; + + return { + id: convertId(id), + createdAt: created ? new Date(created).toISOString().replace('Z', '') : undefined, + updatedAt: updated ? new Date(updated).toISOString().replace('Z', '') : undefined, + workspaceId: convertId(workspaceId), + public: !e.isPrivate, + // @ts-ignore + sortPriority: sortKey, // Will be added to Yaak later + base: isParent ?? e.parentId === workspaceId, + model: 'environment', + name: e.name, + variables: Object.entries(e.data).map(([name, value]) => ({ + enabled: true, + name, + value: `${value}`, + })), + }; +} diff --git a/plugins/importer-insomnia/tests/fixtures/basic.output.json b/plugins/importer-insomnia/tests/fixtures/basic.output.json index c1381750c..f640dc7cb 100644 --- a/plugins/importer-insomnia/tests/fixtures/basic.output.json +++ b/plugins/importer-insomnia/tests/fixtures/basic.output.json @@ -3,6 +3,8 @@ "environments": [ { "createdAt": "2025-01-13T15:15:43.767", + "updatedAt": "2025-01-13T15:15:55.209", + "sortPriority": 1736781343767, "base": true, "id": "GENERATE_ID::env_16c0dec5b77c414ae0e419b8f10c3701300c5900", "model": "environment", @@ -18,6 +20,8 @@ }, { "createdAt": "2025-01-13T15:15:58.515", + "updatedAt": "2025-01-13T15:16:34.705", + "sortPriority": 1736781358515, "base": false, "id": "GENERATE_ID::env_799ae3d723ef44af91b4817e5d057e6d", "model": "environment", @@ -33,6 +37,8 @@ }, { "createdAt": "2025-01-13T15:16:14.707", + "updatedAt": "2025-01-13T15:16:31.078", + "sortPriority": 1736781358565, "base": false, "id": "GENERATE_ID::env_030fbfdbb274426ebd78e2e6518f8553", "model": "environment", @@ -50,6 +56,7 @@ "folders": [ { "createdAt": "2025-01-13T15:16:44.718", + "updatedAt": "2025-01-13T15:16:44.718", "folderId": null, "id": "GENERATE_ID::fld_859d1df78261463480b6a3a1419517e3", "model": "folder", @@ -77,6 +84,8 @@ }, "bodyType": "multipart/form-data", "createdAt": "2025-01-13T15:16:46.672", + "sortPriority": -1736781406672, + "updatedAt": "2025-01-13T15:17:53.176", "description": "My description of the request", "folderId": "GENERATE_ID::fld_859d1df78261463480b6a3a1419517e3", "headers": [ @@ -100,7 +109,6 @@ "method": "GET", "model": "http_request", "name": "New Request", - "sortPriority": 0, "url": "${[BASE_URL ]}/foo/:id", "workspaceId": "GENERATE_ID::wrk_d4d92f7c0ee947b89159243506687019" } diff --git a/plugins/importer-insomnia/tests/fixtures/version-5.input.yaml b/plugins/importer-insomnia/tests/fixtures/version-5.input.yaml new file mode 100644 index 000000000..6bbd81f4c --- /dev/null +++ b/plugins/importer-insomnia/tests/fixtures/version-5.input.yaml @@ -0,0 +1,142 @@ +type: collection.insomnia.rest/5.0 +name: Dummy +meta: + id: wrk_c1eacfa750a04f3ea9985ef28043fa53 + created: 1746799305927 + modified: 1746843054272 + description: This is the description +collection: + - name: Top Level + meta: + id: fld_42eb2e2bb22b4cedacbd3d057634e80c + created: 1736781404718 + modified: 1736781404718 + sortKey: -1736781404718 + children: + - url: "{{ _.BASE_URL }}/foo/:id" + name: New Request + meta: + id: req_d72fff2a6b104b91a2ebe9de9edd2785 + created: 1736781406672 + modified: 1736781473176 + isPrivate: false + description: My description of the request + sortKey: -1736781406672 + method: GET + body: + mimeType: multipart/form-data + params: + - id: pair_7c86036ae8ef499dbbc0b43d0800c5a3 + name: form + value: data + disabled: false + parameters: + - id: pair_b22f6ff611cd4250a6e405ca7b713d09 + name: query + value: qqq + disabled: false + headers: + - name: Content-Type + value: multipart/form-data + id: pair_4af845963bd14256b98716617971eecd + - name: User-Agent + value: insomnia/10.3.0 + id: pair_535ffd00ce48462cb1b7258832ade65a + - id: pair_ab4b870278e943cba6babf5a73e213e3 + name: X-Header + value: xxxx + disabled: false + authentication: + type: basic + useISO88591: false + disabled: false + username: user + password: pass + settings: + renderRequestBody: true + encodeUrl: true + followRedirects: global + cookies: + send: true + store: true + rebuildPath: true + pathParameters: + - name: id + value: iii + - url: grpcb.in:9000 + name: New Request + meta: + id: greq_06d659324df94504a4d64632be7106b3 + created: 1746799344864 + modified: 1746799544082 + isPrivate: false + sortKey: -1746799344864 + body: + text: |- + { + "greeting": "Greg" + } + protoFileId: pf_9d45b0dfaccc4bcc9d930746716786c5 + protoMethodName: /hello.HelloService/SayHello + reflectionApi: + enabled: false + url: https://buf.build + module: buf.build/connectrpc/eliza + - url: wss://echo.websocket.org + name: New WebSocket Request + meta: + id: ws-req_5d1a4c7c79494743962e5176f6add270 + created: 1746799553909 + modified: 1746887120958 + sortKey: -1746799553909 + settings: + encodeUrl: true + followRedirects: global + cookies: + send: true + store: true + authentication: + type: basic + useISO88591: false + disabled: false + username: user + password: password + headers: + - name: User-Agent + value: insomnia/11.1.0 +cookieJar: + name: Default Jar + meta: + id: jar_663d5741b072441aa2709a6113371510 + created: 1736781343768 + modified: 1736781343768 +environments: + name: Base Environment + meta: + id: env_20945044d3c8497ca8b717bef750987e + created: 1736781343767 + modified: 1736781355209 + isPrivate: false + data: + BASE_VAR: hello + subEnvironments: + - name: Production + meta: + id: env_6f7728bb7fc04d558d668e954d756ea2 + created: 1736781358515 + modified: 1736781394705 + isPrivate: false + sortKey: 1736781358515 + data: + BASE_URL: https://api.yaak.app + color: "#f22c2c" + - name: Staging + meta: + id: env_976a8b6eb5d44fb6a20150f65c32d243 + created: 1736781374707 + modified: 1736781391078 + isPrivate: false + sortKey: 1736781358565 + data: + BASE_URL: https://api.staging.yaak.app + color: "#206fac" diff --git a/plugins/importer-insomnia/tests/fixtures/version-5.output.json b/plugins/importer-insomnia/tests/fixtures/version-5.output.json new file mode 100644 index 000000000..6b00c40ae --- /dev/null +++ b/plugins/importer-insomnia/tests/fixtures/version-5.output.json @@ -0,0 +1,172 @@ +{ + "resources": { + "environments": [ + { + "createdAt": "2025-01-13T15:15:43.767", + "updatedAt": "2025-01-13T15:15:55.209", + "base": true, + "public": true, + "id": "GENERATE_ID::env_20945044d3c8497ca8b717bef750987e", + "model": "environment", + "name": "Base Environment", + "variables": [ + { + "enabled": true, + "name": "BASE_VAR", + "value": "hello" + } + ], + "workspaceId": "GENERATE_ID::wrk_c1eacfa750a04f3ea9985ef28043fa53" + }, + { + "createdAt": "2025-01-13T15:15:58.515", + "updatedAt": "2025-01-13T15:16:34.705", + "base": false, + "public": true, + "id": "GENERATE_ID::env_6f7728bb7fc04d558d668e954d756ea2", + "model": "environment", + "name": "Production", + "sortPriority": 1736781358515, + "variables": [ + { + "enabled": true, + "name": "BASE_URL", + "value": "https://api.yaak.app" + } + ], + "workspaceId": "GENERATE_ID::wrk_c1eacfa750a04f3ea9985ef28043fa53" + }, + { + "createdAt": "2025-01-13T15:16:14.707", + "updatedAt": "2025-01-13T15:16:31.078", + "base": false, + "public": true, + "id": "GENERATE_ID::env_976a8b6eb5d44fb6a20150f65c32d243", + "model": "environment", + "name": "Staging", + "sortPriority": 1736781358565, + "variables": [ + { + "enabled": true, + "name": "BASE_URL", + "value": "https://api.staging.yaak.app" + } + ], + "workspaceId": "GENERATE_ID::wrk_c1eacfa750a04f3ea9985ef28043fa53" + } + ], + "folders": [ + { + "createdAt": "2025-01-13T15:16:44.718", + "updatedAt": "2025-01-13T15:16:44.718", + "folderId": null, + "id": "GENERATE_ID::fld_42eb2e2bb22b4cedacbd3d057634e80c", + "model": "folder", + "name": "Top Level", + "sortPriority": -1736781404718, + "workspaceId": "GENERATE_ID::wrk_c1eacfa750a04f3ea9985ef28043fa53" + } + ], + "grpcRequests": [ + { + "model": "grpc_request", + "createdAt": "2025-05-09T14:02:24.864", + "folderId": null, + "id": "GENERATE_ID::greq_06d659324df94504a4d64632be7106b3", + "message": "{\n\t\"greeting\": \"Greg\"\n}", + "metadata": [], + "method": "SayHello", + "name": "New Request", + "service": "hello.HelloService", + "sortPriority": -1746799344864, + "updatedAt": "2025-05-09T14:05:44.082", + "url": "grpcb.in:9000", + "workspaceId": "GENERATE_ID::wrk_c1eacfa750a04f3ea9985ef28043fa53" + } + ], + "httpRequests": [ + { + "authentication": { + "password": "pass", + "username": "user" + }, + "authenticationType": "basic", + "body": { + "form": [ + { + "enabled": true, + "file": null, + "name": "form", + "value": "data" + } + ] + }, + "bodyType": "multipart/form-data", + "createdAt": "2025-01-13T15:16:46.672", + "updatedAt": "2025-01-13T15:17:53.176", + "description": "My description of the request", + "folderId": "GENERATE_ID::fld_42eb2e2bb22b4cedacbd3d057634e80c", + "headers": [ + { + "enabled": true, + "name": "Content-Type", + "value": "multipart/form-data" + }, + { + "enabled": true, + "name": "User-Agent", + "value": "insomnia/10.3.0" + }, + { + "enabled": true, + "name": "X-Header", + "value": "xxxx" + } + ], + "id": "GENERATE_ID::req_d72fff2a6b104b91a2ebe9de9edd2785", + "method": "GET", + "model": "http_request", + "name": "New Request", + "sortPriority": -1736781406672, + "url": "${[BASE_URL ]}/foo/:id", + "workspaceId": "GENERATE_ID::wrk_c1eacfa750a04f3ea9985ef28043fa53" + } + ], + "websocketRequests": [ + { + "id": "GENERATE_ID::ws-req_5d1a4c7c79494743962e5176f6add270", + "createdAt": "2025-05-09T14:05:53.909", + "updatedAt": "2025-05-10T14:25:20.958", + "message": "", + "model": "websocket_request", + "name": "New WebSocket Request", + "sortPriority": -1746799553909, + "authenticationType": "basic", + "authentication": { + "password": "password", + "username": "user" + }, + "folderId": null, + "headers": [ + { + "enabled": true, + "name": "User-Agent", + "value": "insomnia/11.1.0" + } + ], + "url": "wss://echo.websocket.org", + "workspaceId": "GENERATE_ID::wrk_c1eacfa750a04f3ea9985ef28043fa53" + } + ], + "workspaces": [ + { + "createdAt": "2025-05-09T14:01:45.927", + "updatedAt": "2025-05-10T02:10:54.272", + "description": "This is the description", + "id": "GENERATE_ID::wrk_c1eacfa750a04f3ea9985ef28043fa53", + "model": "workspace", + "name": "Dummy" + } + ] + } +} diff --git a/plugins/importer-insomnia/tests/index.test.ts b/plugins/importer-insomnia/tests/index.test.ts index 4fb3ecc41..da561926e 100644 --- a/plugins/importer-insomnia/tests/index.test.ts +++ b/plugins/importer-insomnia/tests/index.test.ts @@ -1,6 +1,7 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import { describe, expect, test } from 'vitest'; +import YAML from 'yaml'; import { convertInsomnia } from '../src'; describe('importer-yaak', () => { @@ -14,10 +15,18 @@ describe('importer-yaak', () => { test('Imports ' + fixture, () => { const contents = fs.readFileSync(path.join(p, fixture), 'utf-8'); - const expected = fs.readFileSync(path.join(p, fixture.replace('.input', '.output')), 'utf-8'); + const expected = fs.readFileSync(path.join(p, fixture.replace(/.input\..*/, '.output.json')), 'utf-8'); const result = convertInsomnia(contents); // console.log(JSON.stringify(result, null, 2)) - expect(result).toEqual(JSON.parse(expected)); + expect(result).toEqual(parseJsonOrYaml(expected)); }); } }); + +function parseJsonOrYaml(text: string): unknown { + try { + return JSON.parse(text); + } catch { + return YAML.parse(text); + } +} From 5f8d99ba646698d5215618427b6c2f2dfd923924 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 11 May 2025 06:46:51 -0700 Subject: [PATCH 162/996] Build plugins --- .../plugins/importer-insomnia/build/index.js | 458 +++++++++++++----- 1 file changed, 340 insertions(+), 118 deletions(-) diff --git a/src-tauri/vendored/plugins/importer-insomnia/build/index.js b/src-tauri/vendored/plugins/importer-insomnia/build/index.js index 72df1fc42..43ad5453f 100644 --- a/src-tauri/vendored/plugins/importer-insomnia/build/index.js +++ b/src-tauri/vendored/plugins/importer-insomnia/build/index.js @@ -7296,35 +7296,48 @@ __export(src_exports, { }); module.exports = __toCommonJS(src_exports); var import_yaml = __toESM(require_dist()); -var plugin = { - importer: { - name: "Insomnia", - description: "Import Insomnia workspaces", - onImport(_ctx, args) { - return convertInsomnia(args.text); - } - } -}; -function convertInsomnia(contents) { - let parsed; - try { - parsed = JSON.parse(contents); - } catch (e) { + +// src/common.ts +function convertSyntax(variable) { + if (!isJSString(variable)) return variable; + return variable.replaceAll(/{{\s*(_\.)?([^}]+)\s*}}/g, "${[$2]}"); +} +function isJSObject(obj) { + return Object.prototype.toString.call(obj) === "[object Object]"; +} +function isJSString(obj) { + return Object.prototype.toString.call(obj) === "[object String]"; +} +function convertId(id) { + if (id.startsWith("GENERATE_ID::")) { + return id; } - try { - parsed = parsed ?? import_yaml.default.parse(contents); - } catch (e) { + return `GENERATE_ID::${id}`; +} +function deleteUndefinedAttrs(obj) { + if (Array.isArray(obj) && obj != null) { + return obj.map(deleteUndefinedAttrs); + } else if (typeof obj === "object" && obj != null) { + return Object.fromEntries( + Object.entries(obj).filter(([, v]) => v !== void 0).map(([k, v]) => [k, deleteUndefinedAttrs(v)]) + ); + } else { + return obj; } - if (!isJSObject(parsed)) return; - if (!Array.isArray(parsed.resources)) return; +} + +// src/v4.ts +function convertInsomniaV4(parsed) { + if (!Array.isArray(parsed.resources)) return null; const resources = { - workspaces: [], - httpRequests: [], - grpcRequests: [], environments: [], - folders: [] + folders: [], + grpcRequests: [], + httpRequests: [], + websocketRequests: [], + workspaces: [] }; - const workspacesToImport = parsed.resources.filter(isWorkspace); + const workspacesToImport = parsed.resources.filter((r) => isJSObject(r) && r._type === "workspace"); for (const w of workspacesToImport) { resources.workspaces.push({ id: convertId(w._id), @@ -7335,25 +7348,25 @@ function convertInsomnia(contents) { description: w.description || void 0 }); const environmentsToImport = parsed.resources.filter( - (r) => isEnvironment(r) + (r) => isJSObject(r) && r._type === "environment" ); resources.environments.push( ...environmentsToImport.map((r) => importEnvironment(r, w._id)) ); const nextFolder = (parentId) => { const children = parsed.resources.filter((r) => r.parentId === parentId); - let sortPriority = 0; for (const child of children) { - if (isRequestGroup(child)) { + if (!isJSObject(child)) continue; + if (child._type === "request_group") { resources.folders.push(importFolder(child, w._id)); nextFolder(child._id); - } else if (isHttpRequest(child)) { + } else if (child._type === "request") { resources.httpRequests.push( - importHttpRequest(child, w._id, sortPriority++) + importHttpRequest(child, w._id) ); - } else if (isGrpcRequest(child)) { + } else if (child._type === "grpc_request") { resources.grpcRequests.push( - importGrpcRequest(child, w._id, sortPriority++) + importGrpcRequest(child, w._id) ); } } @@ -7364,48 +7377,89 @@ function convertInsomnia(contents) { resources.grpcRequests = resources.grpcRequests.filter(Boolean); resources.environments = resources.environments.filter(Boolean); resources.workspaces = resources.workspaces.filter(Boolean); - return { resources: deleteUndefinedAttrs(resources) }; + return { resources }; } -function importEnvironment(e, workspaceId) { - return { - id: convertId(e._id), - createdAt: e.created ? new Date(e.created).toISOString().replace("Z", "") : void 0, - updatedAt: e.updated ? new Date(e.updated).toISOString().replace("Z", "") : void 0, - workspaceId: convertId(workspaceId), - base: e.parentId === workspaceId ? true : false, - model: "environment", - name: e.name, - variables: Object.entries(e.data).map(([name, value]) => ({ - enabled: true, - name, - value: `${value}` - })) - }; -} -function importFolder(f, workspaceId) { +function importHttpRequest(r, workspaceId) { + let bodyType = null; + let body = {}; + if (r.body.mimeType === "application/octet-stream") { + bodyType = "binary"; + body = { filePath: r.body.fileName ?? "" }; + } else if (r.body?.mimeType === "application/x-www-form-urlencoded") { + bodyType = "application/x-www-form-urlencoded"; + body = { + form: (r.body.params ?? []).map((p) => ({ + enabled: !p.disabled, + name: p.name ?? "", + value: p.value ?? "" + })) + }; + } else if (r.body?.mimeType === "multipart/form-data") { + bodyType = "multipart/form-data"; + body = { + form: (r.body.params ?? []).map((p) => ({ + enabled: !p.disabled, + name: p.name ?? "", + value: p.value ?? "", + file: p.fileName ?? null + })) + }; + } else if (r.body?.mimeType === "application/graphql") { + bodyType = "graphql"; + body = { text: convertSyntax(r.body.text ?? "") }; + } else if (r.body?.mimeType === "application/json") { + bodyType = "application/json"; + body = { text: convertSyntax(r.body.text ?? "") }; + } + let authenticationType = null; + let authentication = {}; + if (r.authentication.type === "bearer") { + authenticationType = "bearer"; + authentication = { + token: convertSyntax(r.authentication.token) + }; + } else if (r.authentication.type === "basic") { + authenticationType = "basic"; + authentication = { + username: convertSyntax(r.authentication.username), + password: convertSyntax(r.authentication.password) + }; + } return { - id: convertId(f._id), - createdAt: f.created ? new Date(f.created).toISOString().replace("Z", "") : void 0, - updatedAt: f.updated ? new Date(f.updated).toISOString().replace("Z", "") : void 0, - folderId: f.parentId === workspaceId ? null : convertId(f.parentId), + id: convertId(r.meta?.id ?? r._id), + createdAt: r.created ? new Date(r.created).toISOString().replace("Z", "") : void 0, + updatedAt: r.modified ? new Date(r.modified).toISOString().replace("Z", "") : void 0, workspaceId: convertId(workspaceId), - description: f.description || void 0, - model: "folder", - name: f.name + folderId: r.parentId === workspaceId ? null : convertId(r.parentId), + model: "http_request", + sortPriority: r.metaSortKey, + name: r.name, + description: r.description || void 0, + url: convertSyntax(r.url), + body, + bodyType, + authentication, + authenticationType, + method: r.method, + headers: (r.headers ?? []).map((h) => ({ + enabled: !h.disabled, + name: h.name ?? "", + value: h.value ?? "" + })).filter(({ name, value }) => name !== "" || value !== "") }; } -function importGrpcRequest(r, workspaceId, sortPriority = 0) { +function importGrpcRequest(r, workspaceId) { const parts = r.protoMethodName.split("/").filter((p) => p !== ""); const service = parts[0] ?? null; const method = parts[1] ?? null; return { - id: convertId(r._id), + id: convertId(r.meta?.id ?? r._id), createdAt: r.created ? new Date(r.created).toISOString().replace("Z", "") : void 0, - updatedAt: r.updated ? new Date(r.updated).toISOString().replace("Z", "") : void 0, + updatedAt: r.modified ? new Date(r.modified).toISOString().replace("Z", "") : void 0, workspaceId: convertId(workspaceId), folderId: r.parentId === workspaceId ? null : convertId(r.parentId), model: "grpc_request", - sortPriority, + sortPriority: r.metaSortKey, name: r.name, description: r.description || void 0, url: convertSyntax(r.url), @@ -7419,7 +7473,95 @@ function importGrpcRequest(r, workspaceId, sortPriority = 0) { })).filter(({ name, value }) => name !== "" || value !== "") }; } -function importHttpRequest(r, workspaceId, sortPriority = 0) { +function importFolder(f, workspaceId) { + return { + id: convertId(f._id), + createdAt: f.created ? new Date(f.created).toISOString().replace("Z", "") : void 0, + updatedAt: f.modified ? new Date(f.modified).toISOString().replace("Z", "") : void 0, + folderId: f.parentId === workspaceId ? null : convertId(f.parentId), + workspaceId: convertId(workspaceId), + description: f.description || void 0, + model: "folder", + name: f.name + }; +} +function importEnvironment(e, workspaceId, isParent) { + return { + id: convertId(e._id), + createdAt: e.created ? new Date(e.created).toISOString().replace("Z", "") : void 0, + updatedAt: e.modified ? new Date(e.modified).toISOString().replace("Z", "") : void 0, + workspaceId: convertId(workspaceId), + // @ts-ignore + sortPriority: e.metaSortKey, + // Will be added to Yaak later + base: isParent ?? e.parentId === workspaceId, + model: "environment", + name: e.name, + variables: Object.entries(e.data).map(([name, value]) => ({ + enabled: true, + name, + value: `${value}` + })) + }; +} + +// src/v5.ts +function convertInsomniaV5(parsed) { + if (!Array.isArray(parsed.collection)) return null; + const resources = { + environments: [], + folders: [], + grpcRequests: [], + httpRequests: [], + websocketRequests: [], + workspaces: [] + }; + const meta = parsed.meta ?? {}; + resources.workspaces.push({ + id: convertId(meta.id ?? "collection"), + createdAt: meta.created ? new Date(meta.created).toISOString().replace("Z", "") : void 0, + updatedAt: meta.modified ? new Date(meta.modified).toISOString().replace("Z", "") : void 0, + model: "workspace", + name: parsed.name, + description: meta.description || void 0 + }); + resources.environments.push( + importEnvironment2(parsed.environments, meta.id, true), + ...(parsed.environments.subEnvironments ?? []).map((r) => importEnvironment2(r, meta.id)) + ); + const nextFolder = (children, parentId) => { + for (const child of children ?? []) { + if (!isJSObject(child)) continue; + if (Array.isArray(child.children)) { + resources.folders.push(importFolder2(child, meta.id, parentId)); + nextFolder(child.children, child.meta.id); + } else if (child.method) { + resources.httpRequests.push( + importHttpRequest2(child, meta.id, parentId) + ); + } else if (child.protoFileId) { + resources.grpcRequests.push( + importGrpcRequest2(child, meta.id, parentId) + ); + } else if (child.url) { + resources.websocketRequests.push( + importWebsocketRequest(child, meta.id, parentId) + ); + } + } + }; + nextFolder(parsed.collection ?? [], meta.id); + resources.httpRequests = resources.httpRequests.filter(Boolean); + resources.grpcRequests = resources.grpcRequests.filter(Boolean); + resources.environments = resources.environments.filter(Boolean); + resources.workspaces = resources.workspaces.filter(Boolean); + return { resources }; +} +function importHttpRequest2(r, workspaceId, parentId) { + const id = r.meta?.id ?? r._id; + const created = r.meta?.created ?? r.created; + const updated = r.meta?.modified ?? r.updated; + const sortKey = r.meta?.sortKey ?? r.sortKey; let bodyType = null; let body = {}; if (r.body.mimeType === "application/octet-stream") { @@ -7451,84 +7593,164 @@ function importHttpRequest(r, workspaceId, sortPriority = 0) { bodyType = "application/json"; body = { text: convertSyntax(r.body.text ?? "") }; } - let authenticationType = null; - let authentication = {}; - if (r.authentication.type === "bearer") { - authenticationType = "bearer"; - authentication = { - token: convertSyntax(r.authentication.token) - }; - } else if (r.authentication.type === "basic") { - authenticationType = "basic"; - authentication = { - username: convertSyntax(r.authentication.username), - password: convertSyntax(r.authentication.password) - }; - } return { - id: convertId(r._id), - createdAt: r.created ? new Date(r.created).toISOString().replace("Z", "") : void 0, - updatedAt: r.updated ? new Date(r.updated).toISOString().replace("Z", "") : void 0, + id: convertId(id), workspaceId: convertId(workspaceId), - folderId: r.parentId === workspaceId ? null : convertId(r.parentId), + createdAt: created ? new Date(created).toISOString().replace("Z", "") : void 0, + updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : void 0, + folderId: parentId === workspaceId ? null : convertId(parentId), + sortPriority: sortKey, model: "http_request", - sortPriority, name: r.name, - description: r.description || void 0, + description: r.meta?.description || void 0, url: convertSyntax(r.url), body, bodyType, - authentication, - authenticationType, method: r.method, - headers: (r.headers ?? []).map((h) => ({ + ...importHeaders(r), + ...importAuthentication(r) + }; +} +function importGrpcRequest2(r, workspaceId, parentId) { + const id = r.meta?.id ?? r._id; + const created = r.meta?.created ?? r.created; + const updated = r.meta?.modified ?? r.updated; + const sortKey = r.meta?.sortKey ?? r.sortKey; + const parts = r.protoMethodName.split("/").filter((p) => p !== ""); + const service = parts[0] ?? null; + const method = parts[1] ?? null; + return { + model: "grpc_request", + id: convertId(id), + workspaceId: convertId(workspaceId), + createdAt: created ? new Date(created).toISOString().replace("Z", "") : void 0, + updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : void 0, + folderId: parentId === workspaceId ? null : convertId(parentId), + sortPriority: sortKey, + name: r.name, + description: r.description || void 0, + url: convertSyntax(r.url), + service, + method, + message: r.body?.text ?? "", + metadata: (r.metadata ?? []).map((h) => ({ enabled: !h.disabled, name: h.name ?? "", value: h.value ?? "" })).filter(({ name, value }) => name !== "" || value !== "") }; } -function convertSyntax(variable) { - if (!isJSString(variable)) return variable; - return variable.replaceAll(/{{\s*(_\.)?([^}]+)\s*}}/g, "${[$2]}"); -} -function isWorkspace(obj) { - return isJSObject(obj) && obj._type === "workspace"; -} -function isRequestGroup(obj) { - return isJSObject(obj) && obj._type === "request_group"; -} -function isHttpRequest(obj) { - return isJSObject(obj) && obj._type === "request"; +function importWebsocketRequest(r, workspaceId, parentId) { + const id = r.meta?.id ?? r._id; + const created = r.meta?.created ?? r.created; + const updated = r.meta?.modified ?? r.updated; + const sortKey = r.meta?.sortKey ?? r.sortKey; + return { + model: "websocket_request", + id: convertId(id), + workspaceId: convertId(workspaceId), + createdAt: created ? new Date(created).toISOString().replace("Z", "") : void 0, + updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : void 0, + folderId: parentId === workspaceId ? null : convertId(parentId), + sortPriority: sortKey, + name: r.name, + description: r.description || void 0, + url: convertSyntax(r.url), + message: r.body?.text ?? "", + ...importHeaders(r), + ...importAuthentication(r) + }; } -function isGrpcRequest(obj) { - return isJSObject(obj) && obj._type === "grpc_request"; +function importHeaders(r) { + const headers = (r.headers ?? []).map((h) => ({ + enabled: !h.disabled, + name: h.name ?? "", + value: h.value ?? "" + })).filter(({ name, value }) => name !== "" || value !== ""); + return { headers }; } -function isEnvironment(obj) { - return isJSObject(obj) && obj._type === "environment"; +function importAuthentication(r) { + let authenticationType = null; + let authentication = {}; + if (r.authentication?.type === "bearer") { + authenticationType = "bearer"; + authentication = { + token: convertSyntax(r.authentication.token) + }; + } else if (r.authentication?.type === "basic") { + authenticationType = "basic"; + authentication = { + username: convertSyntax(r.authentication.username), + password: convertSyntax(r.authentication.password) + }; + } + return { authenticationType, authentication }; } -function isJSObject(obj) { - return Object.prototype.toString.call(obj) === "[object Object]"; +function importFolder2(f, workspaceId, parentId) { + const id = f.meta?.id ?? f._id; + const created = f.meta?.created ?? f.created; + const updated = f.meta?.modified ?? f.updated; + const sortKey = f.meta?.sortKey ?? f.sortKey; + return { + model: "folder", + id: convertId(id), + createdAt: created ? new Date(created).toISOString().replace("Z", "") : void 0, + updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : void 0, + folderId: parentId === workspaceId ? null : convertId(parentId), + sortPriority: sortKey, + workspaceId: convertId(workspaceId), + description: f.description || void 0, + name: f.name + }; } -function isJSString(obj) { - return Object.prototype.toString.call(obj) === "[object String]"; +function importEnvironment2(e, workspaceId, isParent) { + const id = e.meta?.id ?? e._id; + const created = e.meta?.created ?? e.created; + const updated = e.meta?.modified ?? e.updated; + const sortKey = e.meta?.sortKey ?? e.sortKey; + return { + id: convertId(id), + createdAt: created ? new Date(created).toISOString().replace("Z", "") : void 0, + updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : void 0, + workspaceId: convertId(workspaceId), + public: !e.isPrivate, + // @ts-ignore + sortPriority: sortKey, + // Will be added to Yaak later + base: isParent ?? e.parentId === workspaceId, + model: "environment", + name: e.name, + variables: Object.entries(e.data).map(([name, value]) => ({ + enabled: true, + name, + value: `${value}` + })) + }; } -function convertId(id) { - if (id.startsWith("GENERATE_ID::")) { - return id; + +// src/index.ts +var plugin = { + importer: { + name: "Insomnia", + description: "Import Insomnia workspaces", + async onImport(_ctx, args) { + return convertInsomnia(args.text); + } } - return `GENERATE_ID::${id}`; -} -function deleteUndefinedAttrs(obj) { - if (Array.isArray(obj) && obj != null) { - return obj.map(deleteUndefinedAttrs); - } else if (typeof obj === "object" && obj != null) { - return Object.fromEntries( - Object.entries(obj).filter(([, v]) => v !== void 0).map(([k, v]) => [k, deleteUndefinedAttrs(v)]) - ); - } else { - return obj; +}; +function convertInsomnia(contents) { + let parsed; + try { + parsed = JSON.parse(contents); + } catch (e) { + } + try { + parsed = parsed ?? import_yaml.default.parse(contents); + } catch (e) { } + if (!isJSObject(parsed)) return null; + const result = convertInsomniaV5(parsed) ?? convertInsomniaV4(parsed); + return deleteUndefinedAttrs(result); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { From 035fe54df0c01eb7ec2a04a14dc5e7cc18c45e13 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 11 May 2025 07:20:57 -0700 Subject: [PATCH 163/996] Send grpc metadata/auth with reflection requests Closes https://feedback.yaak.app/p/send-metadata-during-grpc-reflection --- src-tauri/src/grpc.rs | 53 +++++++++++++++++++++++++- src-tauri/src/lib.rs | 55 ++++++--------------------- src-tauri/yaak-grpc/src/client.rs | 17 ++++++--- src-tauri/yaak-grpc/src/manager.rs | 22 +++++++---- src-tauri/yaak-grpc/src/reflection.rs | 48 +++++++++++++++++------ 5 files changed, 124 insertions(+), 71 deletions(-) diff --git a/src-tauri/src/grpc.rs b/src-tauri/src/grpc.rs index f3ec14f61..94ab06f46 100644 --- a/src-tauri/src/grpc.rs +++ b/src-tauri/src/grpc.rs @@ -1,10 +1,14 @@ use std::collections::BTreeMap; +use crate::error::Result; use KeyAndValueRef::{Ascii, Binary}; - +use tauri::{Manager, Runtime, WebviewWindow}; use yaak_grpc::{KeyAndValueRef, MetadataMap}; +use yaak_models::models::GrpcRequest; +use yaak_plugins::events::{CallHttpAuthenticationRequest, HttpHeader}; +use yaak_plugins::manager::PluginManager; -pub fn metadata_to_map(metadata: MetadataMap) -> BTreeMap { +pub(crate) fn metadata_to_map(metadata: MetadataMap) -> BTreeMap { let mut entries = BTreeMap::new(); for r in metadata.iter() { match r { @@ -14,3 +18,48 @@ pub fn metadata_to_map(metadata: MetadataMap) -> BTreeMap { } entries } + +pub(crate) async fn build_metadata( + window: &WebviewWindow, + request: &GrpcRequest, +) -> Result> { + let plugin_manager = window.state::(); + let mut metadata = BTreeMap::new(); + + // Add the rest of metadata + for h in request.clone().metadata { + if h.name.is_empty() && h.value.is_empty() { + continue; + } + + if !h.enabled { + continue; + } + + metadata.insert(h.name, h.value); + } + + if let Some(auth_name) = request.authentication_type.clone() { + let auth = request.authentication.clone(); + let plugin_req = CallHttpAuthenticationRequest { + context_id: format!("{:x}", md5::compute(request.id.clone())), + values: serde_json::from_value(serde_json::to_value(&auth).unwrap()).unwrap(), + method: "POST".to_string(), + url: request.url.clone(), + headers: metadata + .iter() + .map(|(name, value)| HttpHeader { + name: name.to_string(), + value: value.to_string(), + }) + .collect(), + }; + let plugin_result = + plugin_manager.call_http_authentication(&window, &auth_name, plugin_req).await?; + for header in plugin_result.set_headers { + metadata.insert(header.name, header.value); + } + } + + Ok(metadata) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 8fcdaf28b..000d37727 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,7 +1,7 @@ extern crate core; use crate::encoding::read_response_body; use crate::error::Error::GenericError; -use crate::grpc::metadata_to_map; +use crate::grpc::{build_metadata, metadata_to_map}; use crate::http_request::send_http_request; use crate::notifications::YaakNotifier; use crate::render::{render_grpc_request, render_template}; @@ -38,9 +38,9 @@ use yaak_models::util::{ BatchUpsertResult, UpdateSource, get_workspace_export_resources, maybe_gen_id, maybe_gen_id_opt, }; use yaak_plugins::events::{ - BootResponse, CallHttpAuthenticationRequest, CallHttpRequestActionRequest, FilterResponse, + BootResponse, CallHttpRequestActionRequest, FilterResponse, GetHttpAuthenticationConfigResponse, GetHttpAuthenticationSummaryResponse, - GetHttpRequestActionsResponse, GetTemplateFunctionsResponse, HttpHeader, InternalEvent, + GetHttpRequestActionsResponse, GetTemplateFunctionsResponse, InternalEvent, InternalEventPayload, JsonPrimitive, PluginWindowContext, RenderPurpose, }; use yaak_plugins::manager::PluginManager; @@ -166,6 +166,7 @@ async fn cmd_grpc_reflect( .await?; let uri = safe_uri(&req.url); + let metadata = build_metadata(&window, &req).await?; Ok(grpc_handle .lock() @@ -174,6 +175,7 @@ async fn cmd_grpc_reflect( &req.id, &uri, &proto_files.iter().map(|p| PathBuf::from_str(p).unwrap()).collect(), + &metadata, ) .await .map_err(|e| GenericError(e.to_string()))?) @@ -186,7 +188,6 @@ async fn cmd_grpc_go( proto_files: Vec, app_handle: AppHandle, window: WebviewWindow, - plugin_manager: State<'_, PluginManager>, grpc_handle: State<'_, Mutex>, ) -> YaakResult { let environment = match environment_id { @@ -208,42 +209,7 @@ async fn cmd_grpc_go( ) .await?; - let mut metadata = BTreeMap::new(); - - // Add the rest of metadata - for h in request.clone().metadata { - if h.name.is_empty() && h.value.is_empty() { - continue; - } - - if !h.enabled { - continue; - } - - metadata.insert(h.name, h.value); - } - - if let Some(auth_name) = request.authentication_type.clone() { - let auth = request.authentication.clone(); - let plugin_req = CallHttpAuthenticationRequest { - context_id: format!("{:x}", md5::compute(request_id.to_string())), - values: serde_json::from_value(serde_json::to_value(&auth).unwrap()).unwrap(), - method: "POST".to_string(), - url: request.url.clone(), - headers: metadata - .iter() - .map(|(name, value)| HttpHeader { - name: name.to_string(), - value: value.to_string(), - }) - .collect(), - }; - let plugin_result = - plugin_manager.call_http_authentication(&window, &auth_name, plugin_req).await?; - for header in plugin_result.set_headers { - metadata.insert(header.name, header.value); - } - } + let metadata = build_metadata(&window, &request).await?; let conn = app_handle.db().upsert_grpc_connection( &GrpcConnection { @@ -291,6 +257,7 @@ async fn cmd_grpc_go( &request.clone().id, uri.as_str(), &proto_files.iter().map(|p| PathBuf::from_str(p).unwrap()).collect(), + &metadata, ) .await; @@ -448,7 +415,7 @@ async fn cmd_grpc_go( match (method_desc.is_client_streaming(), method_desc.is_server_streaming()) { (true, true) => ( Some( - connection.streaming(&service, &method, in_msg_stream, metadata).await, + connection.streaming(&service, &method, in_msg_stream, &metadata).await, ), None, ), @@ -456,16 +423,16 @@ async fn cmd_grpc_go( None, Some( connection - .client_streaming(&service, &method, in_msg_stream, metadata) + .client_streaming(&service, &method, in_msg_stream, &metadata) .await, ), ), (false, true) => ( - Some(connection.server_streaming(&service, &method, &msg, metadata).await), + Some(connection.server_streaming(&service, &method, &msg, &metadata).await), None, ), (false, false) => { - (None, Some(connection.unary(&service, &method, &msg, metadata).await)) + (None, Some(connection.unary(&service, &method, &msg, &metadata).await)) } }; diff --git a/src-tauri/yaak-grpc/src/client.rs b/src-tauri/yaak-grpc/src/client.rs index c7d1afe65..5c185368e 100644 --- a/src-tauri/yaak-grpc/src/client.rs +++ b/src-tauri/yaak-grpc/src/client.rs @@ -1,13 +1,15 @@ +use crate::manager::decorate_req; use crate::transport::get_transport; use async_recursion::async_recursion; use hyper_rustls::HttpsConnector; -use hyper_util::client::legacy::connect::HttpConnector; use hyper_util::client::legacy::Client; +use hyper_util::client::legacy::connect::HttpConnector; use log::debug; +use std::collections::BTreeMap; use tokio_stream::StreamExt; +use tonic::Request; use tonic::body::BoxBody; use tonic::transport::Uri; -use tonic::Request; use tonic_reflection::pb::v1::server_reflection_request::MessageRequest; use tonic_reflection::pb::v1::server_reflection_response::MessageResponse; use tonic_reflection::pb::v1::{ @@ -44,6 +46,7 @@ impl AutoReflectionClient { pub async fn send_reflection_request( &mut self, message: MessageRequest, + metadata: &BTreeMap, ) -> Result { let reflection_request = ServerReflectionRequest { host: "".into(), // Doesn't matter @@ -51,7 +54,9 @@ impl AutoReflectionClient { }; if self.use_v1alpha { - let request = Request::new(tokio_stream::once(to_v1alpha_request(reflection_request))); + let mut request = Request::new(tokio_stream::once(to_v1alpha_request(reflection_request))); + decorate_req(metadata, &mut request).map_err(|e| e.to_string())?; + self.client_v1alpha .server_reflection_info(request) .await @@ -70,7 +75,9 @@ impl AutoReflectionClient { .ok_or("No reflection response".to_string()) .map(|resp| to_v1_msg_response(resp)) } else { - let request = Request::new(tokio_stream::once(reflection_request)); + let mut request = Request::new(tokio_stream::once(reflection_request)); + decorate_req(metadata, &mut request).map_err(|e| e.to_string())?; + let resp = self.client_v1.server_reflection_info(request).await; match resp { Ok(r) => Ok(r), @@ -79,7 +86,7 @@ impl AutoReflectionClient { // If v1 fails, change to v1alpha and try again debug!("gRPC schema reflection falling back to v1alpha"); self.use_v1alpha = true; - return self.send_reflection_request(message).await; + return self.send_reflection_request(message, metadata).await; } _ => Err(e), }, diff --git a/src-tauri/yaak-grpc/src/manager.rs b/src-tauri/yaak-grpc/src/manager.rs index a39b59a97..c4e19efc1 100644 --- a/src-tauri/yaak-grpc/src/manager.rs +++ b/src-tauri/yaak-grpc/src/manager.rs @@ -69,7 +69,7 @@ impl GrpcConnection { service: &str, method: &str, message: &str, - metadata: BTreeMap, + metadata: &BTreeMap, ) -> Result, StreamError> { let method = &self.method(&service, &method)?; let input_message = method.input(); @@ -96,7 +96,7 @@ impl GrpcConnection { service: &str, method: &str, stream: ReceiverStream, - metadata: BTreeMap, + metadata: &BTreeMap, ) -> Result>, StreamError> { let method = &self.method(&service, &method)?; let mut client = tonic::client::Grpc::with_origin(self.conn.clone(), self.uri.clone()); @@ -116,7 +116,7 @@ impl GrpcConnection { service: &str, method: &str, stream: ReceiverStream, - metadata: BTreeMap, + metadata: &BTreeMap, ) -> Result, StreamError> { let method = &self.method(&service, &method)?; let mut client = tonic::client::Grpc::with_origin(self.conn.clone(), self.uri.clone()); @@ -137,7 +137,7 @@ impl GrpcConnection { service: &str, method: &str, message: &str, - metadata: BTreeMap, + metadata: &BTreeMap, ) -> Result>, StreamError> { let method = &self.method(&service, &method)?; let input_message = method.input(); @@ -180,10 +180,11 @@ impl GrpcHandle { id: &str, uri: &str, proto_files: &Vec, + metadata: &BTreeMap, ) -> Result<(), String> { let pool = if proto_files.is_empty() { let full_uri = uri_from_str(uri)?; - fill_pool_from_reflection(&full_uri).await + fill_pool_from_reflection(&full_uri, metadata).await } else { fill_pool_from_files(&self.app_handle, proto_files).await }?; @@ -197,9 +198,10 @@ impl GrpcHandle { id: &str, uri: &str, proto_files: &Vec, + metadata: &BTreeMap, ) -> Result, String> { // Ensure reflection is up-to-date - self.reflect(id, uri, proto_files).await?; + self.reflect(id, uri, proto_files, metadata).await?; let pool = self.get_pool(id, uri, proto_files).ok_or("Failed to get pool".to_string())?; Ok(self.services_from_pool(&pool)) @@ -235,8 +237,9 @@ impl GrpcHandle { id: &str, uri: &str, proto_files: &Vec, + metadata: &BTreeMap, ) -> Result { - self.reflect(id, uri, proto_files).await?; + self.reflect(id, uri, proto_files, metadata).await?; let pool = self.get_pool(id, uri, proto_files).ok_or("Failed to get pool")?; let uri = uri_from_str(uri)?; @@ -254,7 +257,10 @@ impl GrpcHandle { } } -fn decorate_req(metadata: BTreeMap, req: &mut Request) -> Result<(), String> { +pub(crate) fn decorate_req( + metadata: &BTreeMap, + req: &mut Request, +) -> Result<(), String> { for (k, v) in metadata { req.metadata_mut().insert( MetadataKey::from_str(k.as_str()).map_err(|e| e.to_string())?, diff --git a/src-tauri/yaak-grpc/src/reflection.rs b/src-tauri/yaak-grpc/src/reflection.rs index 27db0a88d..1449a6d85 100644 --- a/src-tauri/yaak-grpc/src/reflection.rs +++ b/src-tauri/yaak-grpc/src/reflection.rs @@ -1,3 +1,4 @@ +use std::collections::BTreeMap; use std::env::temp_dir; use std::ops::Deref; use std::path::PathBuf; @@ -89,11 +90,14 @@ pub async fn fill_pool_from_files( Ok(pool) } -pub async fn fill_pool_from_reflection(uri: &Uri) -> Result { +pub async fn fill_pool_from_reflection( + uri: &Uri, + metadata: &BTreeMap, +) -> Result { let mut pool = DescriptorPool::new(); let mut client = AutoReflectionClient::new(uri); - for service in list_services(&mut client).await? { + for service in list_services(&mut client, metadata).await? { if service == "grpc.reflection.v1alpha.ServerReflection" { continue; } @@ -101,14 +105,18 @@ pub async fn fill_pool_from_reflection(uri: &Uri) -> Result Result, String> { - let response = client.send_reflection_request(MessageRequest::ListServices("".into())).await?; +async fn list_services( + client: &mut AutoReflectionClient, + metadata: &BTreeMap, +) -> Result, String> { + let response = + client.send_reflection_request(MessageRequest::ListServices("".into()), metadata).await?; let list_services_response = match response { MessageResponse::ListServicesResponse(resp) => resp, @@ -122,9 +130,13 @@ async fn file_descriptor_set_from_service_name( service_name: &str, pool: &mut DescriptorPool, client: &mut AutoReflectionClient, + metadata: &BTreeMap, ) { let response = match client - .send_reflection_request(MessageRequest::FileContainingSymbol(service_name.into())) + .send_reflection_request( + MessageRequest::FileContainingSymbol(service_name.into()), + metadata, + ) .await { Ok(resp) => resp, @@ -139,8 +151,13 @@ async fn file_descriptor_set_from_service_name( _ => panic!("Expected a FileDescriptorResponse variant"), }; - add_file_descriptors_to_pool(file_descriptor_response.file_descriptor_proto, pool, client) - .await; + add_file_descriptors_to_pool( + file_descriptor_response.file_descriptor_proto, + pool, + client, + metadata, + ) + .await; } #[async_recursion] @@ -148,6 +165,7 @@ async fn add_file_descriptors_to_pool( fds: Vec>, pool: &mut DescriptorPool, client: &mut AutoReflectionClient, + metadata: &BTreeMap, ) { let mut topo_sort = topology::SimpleTopoSort::new(); let mut fd_mapping = std::collections::HashMap::with_capacity(fds.len()); @@ -165,7 +183,7 @@ async fn add_file_descriptors_to_pool( if let Some(fdp) = fd_mapping.remove(&node) { pool.add_file_descriptor_proto(fdp).expect("add file descriptor proto"); } else { - file_descriptor_set_by_filename(node.as_str(), pool, client).await; + file_descriptor_set_by_filename(node.as_str(), pool, client, metadata).await; } } Err(_) => panic!("proto file got cycle!"), @@ -177,6 +195,7 @@ async fn file_descriptor_set_by_filename( filename: &str, pool: &mut DescriptorPool, client: &mut AutoReflectionClient, + metadata: &BTreeMap, ) { // We already fetched this file if let Some(_) = pool.get_file_by_name(filename) { @@ -184,7 +203,7 @@ async fn file_descriptor_set_by_filename( } let msg = MessageRequest::FileByFilename(filename.into()); - let response = client.send_reflection_request(msg).await; + let response = client.send_reflection_request(msg, metadata).await; let file_descriptor_response = match response { Ok(MessageResponse::FileDescriptorResponse(resp)) => resp, Ok(_) => { @@ -196,8 +215,13 @@ async fn file_descriptor_set_by_filename( } }; - add_file_descriptors_to_pool(file_descriptor_response.file_descriptor_proto, pool, client) - .await; + add_file_descriptors_to_pool( + file_descriptor_response.file_descriptor_proto, + pool, + client, + metadata, + ) + .await; } pub fn method_desc_to_path(md: &MethodDescriptor) -> PathAndQuery { From b3ede3d6d67f3378ada0995fb8950e5fa6ca6840 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 12 May 2025 15:53:21 -0700 Subject: [PATCH 164/996] Add error boundaries --- src-web/components/Dialogs.tsx | 24 +++---- src-web/components/ErrorBoundary.tsx | 68 ++++++++++++++++++++ src-web/components/GrpcResponsePane.tsx | 45 +++++++------ src-web/components/HttpResponsePane.tsx | 61 +++++++++--------- src-web/components/Markdown.tsx | 11 ++-- src-web/components/RouteError.tsx | 2 +- src-web/components/Toasts.tsx | 22 ++++--- src-web/components/WebsocketResponsePane.tsx | 45 +++++++------ src-web/components/Workspace.tsx | 13 +++- src-web/components/core/Dropdown.tsx | 25 +++---- src-web/components/core/Tabs/Tabs.tsx | 17 +++-- 11 files changed, 215 insertions(+), 118 deletions(-) create mode 100644 src-web/components/ErrorBoundary.tsx diff --git a/src-web/components/Dialogs.tsx b/src-web/components/Dialogs.tsx index 2b96f9e31..b96e0f83e 100644 --- a/src-web/components/Dialogs.tsx +++ b/src-web/components/Dialogs.tsx @@ -2,6 +2,7 @@ import { useAtomValue } from 'jotai'; import React from 'react'; import { dialogsAtom, hideDialog } from '../lib/dialog'; import { Dialog, type DialogProps } from './core/Dialog'; +import { ErrorBoundary } from './ErrorBoundary'; export type DialogInstance = { id: string; @@ -22,16 +23,17 @@ export function Dialogs() { function DialogInstance({ render, onClose, id, ...props }: DialogInstance) { const children = render({ hide: () => hideDialog(id) }); return ( - { - onClose?.(); - hideDialog(id); - }} - {...props} - > - {children} - + + { + onClose?.(); + hideDialog(id); + }} + {...props} + > + {children} + + ); } diff --git a/src-web/components/ErrorBoundary.tsx b/src-web/components/ErrorBoundary.tsx new file mode 100644 index 000000000..5ab7fc116 --- /dev/null +++ b/src-web/components/ErrorBoundary.tsx @@ -0,0 +1,68 @@ +import type { ErrorInfo, ReactNode } from 'react'; +import { Component, useEffect } from 'react'; +import { showDialog } from '../lib/dialog'; +import { Banner } from './core/Banner'; +import { Button } from './core/Button'; +import { InlineCode } from './core/InlineCode'; +import RouteError from './RouteError'; + +interface ErrorBoundaryProps { + name: string; + children: ReactNode; +} + +interface ErrorBoundaryState { + hasError: boolean; + error: Error | null; +} + +export class ErrorBoundary extends Component { + constructor(props: ErrorBoundaryProps) { + super(props); + this.state = { hasError: false, error: null }; + } + + static getDerivedStateFromError(error: Error): ErrorBoundaryState { + return { hasError: true, error }; + } + + componentDidCatch(error: Error, info: ErrorInfo) { + console.warn('Error caught by ErrorBoundary:', error, info); + } + + render() { + if (this.state.hasError) { + return ( + +
+ Error rendering {this.props.name} component +
+ +
+ ); + } + + return this.props.children; + } +} + +export function ErrorBoundaryTestThrow() { + useEffect(() => { + throw new Error('test error'); + }); + + return
Hello
; +} diff --git a/src-web/components/GrpcResponsePane.tsx b/src-web/components/GrpcResponsePane.tsx index 157048fc5..ca0f9dd7f 100644 --- a/src-web/components/GrpcResponsePane.tsx +++ b/src-web/components/GrpcResponsePane.tsx @@ -25,6 +25,7 @@ import { Separator } from './core/Separator'; import { SplitLayout } from './core/SplitLayout'; import { HStack, VStack } from './core/Stacks'; import { EmptyStateText } from './EmptyStateText'; +import { ErrorBoundary } from './ErrorBoundary'; import { RecentGrpcConnectionsDropdown } from './RecentGrpcConnectionsDropdown'; interface Props { @@ -92,27 +93,29 @@ export function GrpcResponsePane({ style, methodType, activeRequest }: Props) { />
- - {activeConnection.error} - - ) - } - render={(event) => ( - { - if (event.id === activeEventId) setActiveEventId(null); - else setActiveEventId(event.id); - }} - /> - )} - /> + + + {activeConnection.error} + + ) + } + render={(event) => ( + { + if (event.id === activeEventId) setActiveEventId(null); + else setActiveEventId(event.id); + }} + /> + )} + /> +
) } diff --git a/src-web/components/HttpResponsePane.tsx b/src-web/components/HttpResponsePane.tsx index cf27cf6eb..79ed88b07 100644 --- a/src-web/components/HttpResponsePane.tsx +++ b/src-web/components/HttpResponsePane.tsx @@ -30,6 +30,7 @@ import { ImageViewer } from './responseViewers/ImageViewer'; import { PdfViewer } from './responseViewers/PdfViewer'; import { SvgViewer } from './responseViewers/SvgViewer'; import { VideoViewer } from './responseViewers/VideoViewer'; +import { ErrorBoundary } from './ErrorBoundary'; interface Props { style?: CSSProperties; @@ -155,35 +156,37 @@ export function HttpResponsePane({ style, className, activeRequestId }: Props) { tabListClassName="mt-1.5" > - - {activeResponse.state === 'initialized' ? ( - - - - ) : activeResponse.state === 'closed' && activeResponse.contentLength === 0 ? ( - Empty - ) : mimeType?.match(/^text\/event-stream/i) && viewMode === 'pretty' ? ( - - ) : mimeType?.match(/^image\/svg/) ? ( - - ) : mimeType?.match(/^image/i) ? ( - - ) : mimeType?.match(/^audio/i) ? ( - - ) : mimeType?.match(/^video/i) ? ( - - ) : mimeType?.match(/pdf/i) ? ( - - ) : mimeType?.match(/csv|tab-separated/i) ? ( - - ) : ( - - )} - + + + {activeResponse.state === 'initialized' ? ( + + + + ) : activeResponse.state === 'closed' && activeResponse.contentLength === 0 ? ( + Empty + ) : mimeType?.match(/^text\/event-stream/i) && viewMode === 'pretty' ? ( + + ) : mimeType?.match(/^image\/svg/) ? ( + + ) : mimeType?.match(/^image/i) ? ( + + ) : mimeType?.match(/^audio/i) ? ( + + ) : mimeType?.match(/^video/i) ? ( + + ) : mimeType?.match(/pdf/i) ? ( + + ) : mimeType?.match(/csv|tab-separated/i) ? ( + + ) : ( + + )} + + diff --git a/src-web/components/Markdown.tsx b/src-web/components/Markdown.tsx index b07b5bafb..52d2bd002 100644 --- a/src-web/components/Markdown.tsx +++ b/src-web/components/Markdown.tsx @@ -1,13 +1,16 @@ -import remarkGfm from 'remark-gfm'; import ReactMarkdown, { type Components } from 'react-markdown'; +import remarkGfm from 'remark-gfm'; +import { ErrorBoundary } from './ErrorBoundary'; import { Prose } from './Prose'; export function Markdown({ children, className }: { children: string; className?: string }) { return ( - - {children} - + + + {children} + + ); } diff --git a/src-web/components/RouteError.tsx b/src-web/components/RouteError.tsx index 7ad05aff8..0e2f12b5e 100644 --- a/src-web/components/RouteError.tsx +++ b/src-web/components/RouteError.tsx @@ -3,7 +3,7 @@ import { FormattedError } from './core/FormattedError'; import { Heading } from './core/Heading'; import { VStack } from './core/Stacks'; -export default function RouteError({ error }: { error: unknown; reset: () => void }) { +export default function RouteError({ error }: { error: unknown }) { console.log('Error', error); const stringified = JSON.stringify(error); // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/src-web/components/Toasts.tsx b/src-web/components/Toasts.tsx index ce0f34a9c..d4c9458f8 100644 --- a/src-web/components/Toasts.tsx +++ b/src-web/components/Toasts.tsx @@ -4,6 +4,7 @@ import React, { type ReactNode } from 'react'; import { hideToast, toastsAtom } from '../lib/toast'; import { Toast, type ToastProps } from './core/Toast'; import { Portal } from './Portal'; +import { ErrorBoundary } from './ErrorBoundary'; export type ToastInstance = { id: string; @@ -22,16 +23,17 @@ export const Toasts = () => { {toasts.map((toast: ToastInstance) => { const { message, uniqueKey, ...props } = toast; return ( - hideToast(toast)} - > - {message} - + + hideToast(toast)} + > + {message} + + ); })} diff --git a/src-web/components/WebsocketResponsePane.tsx b/src-web/components/WebsocketResponsePane.tsx index 4464031d6..db28897c3 100644 --- a/src-web/components/WebsocketResponsePane.tsx +++ b/src-web/components/WebsocketResponsePane.tsx @@ -27,6 +27,7 @@ import { SplitLayout } from './core/SplitLayout'; import { HStack, VStack } from './core/Stacks'; import { WebsocketStatusTag } from './core/WebsocketStatusTag'; import { EmptyStateText } from './EmptyStateText'; +import { ErrorBoundary } from './ErrorBoundary'; import { RecentWebsocketConnectionsDropdown } from './RecentWebsocketConnectionsDropdown'; interface Props { @@ -93,27 +94,29 @@ export function WebsocketResponsePane({ activeRequest }: Props) { /> - - {activeConnection.error} - - ) - } - render={(event) => ( - { - if (event.id === activeEventId) setActiveEventId(null); - else setActiveEventId(event.id); - }} - /> - )} - /> + + + {activeConnection.error} + + ) + } + render={(event) => ( + { + if (event.id === activeEventId) setActiveEventId(null); + else setActiveEventId(event.id); + }} + /> + )} + /> + ) } diff --git a/src-web/components/Workspace.tsx b/src-web/components/Workspace.tsx index 744061c4c..5d49623c7 100644 --- a/src-web/components/Workspace.tsx +++ b/src-web/components/Workspace.tsx @@ -41,6 +41,7 @@ import { Sidebar } from './sidebar/Sidebar'; import { SidebarActions } from './sidebar/SidebarActions'; import { WebsocketRequestLayout } from './WebsocketRequestLayout'; import { WorkspaceHeader } from './WorkspaceHeader'; +import { ErrorBoundary } from './ErrorBoundary'; const side = { gridArea: 'side' }; const head = { gridArea: 'head' }; @@ -149,13 +150,17 @@ export function Workspace() { - + + + ) : ( <>
- + + +
- + + + ); } diff --git a/src-web/components/core/Dropdown.tsx b/src-web/components/core/Dropdown.tsx index 5d82c7ae9..30ad27487 100644 --- a/src-web/components/core/Dropdown.tsx +++ b/src-web/components/core/Dropdown.tsx @@ -37,6 +37,7 @@ import { Icon } from './Icon'; import { LoadingIcon } from './LoadingIcon'; import { Separator } from './Separator'; import { HStack, VStack } from './Stacks'; +import { ErrorBoundary } from '../ErrorBoundary'; export type DropdownItemSeparator = { type: 'separator'; @@ -202,17 +203,19 @@ export const Dropdown = forwardRef(function Dropdown return ( <> {child} - setIsOpen(false)} - isOpen={isOpen} - /> + + setIsOpen(false)} + isOpen={isOpen} + /> + ); }); diff --git a/src-web/components/core/Tabs/Tabs.tsx b/src-web/components/core/Tabs/Tabs.tsx index 2f90c4fe6..001ea59df 100644 --- a/src-web/components/core/Tabs/Tabs.tsx +++ b/src-web/components/core/Tabs/Tabs.tsx @@ -5,6 +5,7 @@ import { Icon } from '../Icon'; import type { RadioDropdownProps } from '../RadioDropdown'; import { RadioDropdown } from '../RadioDropdown'; import { HStack } from '../Stacks'; +import { ErrorBoundary } from '../../ErrorBoundary'; export type TabItem = | { @@ -153,12 +154,14 @@ export const TabContent = memo(function TabContent({ className, }: TabContentProps) { return ( -
- {children} -
+ +
+ {children} +
+
); }); From dad9cebb9e1b95016f0a50f626d40a209de4abb5 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 12 May 2025 16:57:13 -0700 Subject: [PATCH 165/996] Don't send empty ? for ws query params --- src-tauri/yaak-ws/src/commands.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src-tauri/yaak-ws/src/commands.rs b/src-tauri/yaak-ws/src/commands.rs index 25c5d2ead..c1de4f80d 100644 --- a/src-tauri/yaak-ws/src/commands.rs +++ b/src-tauri/yaak-ws/src/commands.rs @@ -5,15 +5,15 @@ use log::{info, warn}; use std::str::FromStr; use tauri::http::{HeaderMap, HeaderName}; use tauri::{AppHandle, Runtime, State, Url, WebviewWindow}; -use tokio::sync::{mpsc, Mutex}; -use tokio_tungstenite::tungstenite::http::HeaderValue; +use tokio::sync::{Mutex, mpsc}; use tokio_tungstenite::tungstenite::Message; +use tokio_tungstenite::tungstenite::http::HeaderValue; use yaak_http::apply_path_placeholders; -use yaak_models::query_manager::QueryManagerExt; use yaak_models::models::{ HttpResponseHeader, WebsocketConnection, WebsocketConnectionState, WebsocketEvent, WebsocketEventType, WebsocketRequest, }; +use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::UpdateSource; use yaak_plugins::events::{ CallHttpAuthenticationRequest, HttpHeader, PluginWindowContext, RenderPurpose, @@ -257,12 +257,16 @@ pub(crate) async fn connect( // Add URL parameters to URL let mut url = Url::parse(&url).unwrap(); { - let mut query_pairs = url.query_pairs_mut(); - for p in url_parameters.clone() { - if !p.enabled || p.name.is_empty() { - continue; + let valid_query_pairs = url_parameters + .into_iter() + .filter(|p| p.enabled && !p.name.is_empty()) + .collect::>(); + // NOTE: Only mutate query pairs if there are any, or it will append an empty `?` to the URL + if !valid_query_pairs.is_empty() { + let mut query_pairs = url.query_pairs_mut(); + for p in valid_query_pairs { + query_pairs.append_pair(p.name.as_str(), p.value.as_str()); } - query_pairs.append_pair(p.name.as_str(), p.value.as_str()); } } From 81e78ef24c6428bdab61eb908c7b07c9742823e0 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 12 May 2025 16:57:43 -0700 Subject: [PATCH 166/996] Fix auth padding --- src-web/components/DynamicForm.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src-web/components/DynamicForm.tsx b/src-web/components/DynamicForm.tsx index 9011678d2..ce4817b53 100644 --- a/src-web/components/DynamicForm.tsx +++ b/src-web/components/DynamicForm.tsx @@ -65,6 +65,7 @@ export function DynamicForm>({ autocompleteFunctions={autocompleteFunctions} autocompleteVariables={autocompleteVariables} data={data} + className="pb-4" // Pad the bottom to look nice /> ); } @@ -77,15 +78,17 @@ function FormInputs>({ setDataAttr, data, disabled, + className, }: Pick< Props, 'inputs' | 'autocompleteFunctions' | 'autocompleteVariables' | 'stateKey' | 'data' > & { setDataAttr: (name: string, value: JsonPrimitive) => void; disabled?: boolean; + className?: string; }) { return ( - + {inputs?.map((input, i) => { if ('hidden' in input && input.hidden) { return null; From 417a02744bb4a621192192815634c67e39bc9d5c Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 12 May 2025 22:19:16 -0700 Subject: [PATCH 167/996] Don't select text when focus is due to window focus Closes https://feedback.yaak.app/p/url-input-auto-selects-all-text-when-regaining-focus-after --- src-web/components/core/Input.tsx | 26 +++++++++++++++++++++----- src-web/hooks/useWindowFocus.ts | 16 +++++++--------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src-web/components/core/Input.tsx b/src-web/components/core/Input.tsx index 95c270c95..6a94fd3f0 100644 --- a/src-web/components/core/Input.tsx +++ b/src-web/components/core/Input.tsx @@ -13,6 +13,7 @@ import { } from 'react'; import { useIsEncryptionEnabled } from '../../hooks/useIsEncryptionEnabled'; import { useStateWithDeps } from '../../hooks/useStateWithDeps'; +import { copyToClipboard } from '../../lib/copy'; import { analyzeTemplate, convertTemplateToInsecure, @@ -30,7 +31,6 @@ import { Icon } from './Icon'; import { IconButton } from './IconButton'; import { Label } from './Label'; import { HStack } from './Stacks'; -import { copyToClipboard } from '../../lib/copy'; export type InputProps = Pick< EditorProps, @@ -127,13 +127,29 @@ const BaseInput = forwardRef(function InputBase( useImperativeHandle(ref, () => editorRef.current); + const lastWindowFocus = useRef(0); + useEffect(() => { + const fn = () => (lastWindowFocus.current = Date.now()); + window.addEventListener('focus', fn); + return () => { + window.removeEventListener('focus', fn); + }; + }, []); + const handleFocus = useCallback(() => { if (readOnly) return; + + // Select all text of input when it's focused to match standard browser behavior. + // This should not, however, select when the input is focused due to a window focus event, so + // we handle that case as well. + const windowJustFocused = Date.now() - lastWindowFocus.current < 200; + if (!windowJustFocused) { + editorRef.current?.dispatch({ + selection: { anchor: 0, head: editorRef.current.state.doc.length }, + }); + } + setFocused(true); - // Select all text on focus - editorRef.current?.dispatch({ - selection: { anchor: 0, head: editorRef.current.state.doc.length }, - }); onFocus?.(); }, [onFocus, readOnly]); diff --git a/src-web/hooks/useWindowFocus.ts b/src-web/hooks/useWindowFocus.ts index de4615d10..f5f2831ef 100644 --- a/src-web/hooks/useWindowFocus.ts +++ b/src-web/hooks/useWindowFocus.ts @@ -5,15 +5,13 @@ export function useWindowFocus() { const [visible, setVisible] = useState(true); useEffect(() => { - let unsub: undefined | (() => void) = undefined; - getCurrentWebviewWindow() - .onFocusChanged((e) => { - setVisible(e.payload); - }) - .then((fn) => { - unsub = fn; - }); - return () => unsub?.(); + const unlisten = getCurrentWebviewWindow().onFocusChanged((e) => { + setVisible(e.payload); + }); + + return () => { + unlisten.then((fn) => fn()); + }; }, []); return visible; From 469d12fedec24907b88c22ec4ce84ae34f3a4d74 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 13 May 2025 10:11:24 -0700 Subject: [PATCH 168/996] Don't query KeyValue.id == NULL --- src-tauri/yaak-models/src/queries/key_values.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src-tauri/yaak-models/src/queries/key_values.rs b/src-tauri/yaak-models/src/queries/key_values.rs index b7ee6f4a0..bfbb05c0e 100644 --- a/src-tauri/yaak-models/src/queries/key_values.rs +++ b/src-tauri/yaak-models/src/queries/key_values.rs @@ -11,6 +11,11 @@ impl<'a> DbContext<'a> { let (sql, params) = Query::select() .from(KeyValueIden::Table) .column(Asterisk) + // Temporary clause to prevent bug when reverting to the previous version, before the + // ID column was added. A previous version will not know about ID and will create + // key/value entries that don't have one. This clause ensures they are not queried + // TODO: Add migration to delete key/values with NULL IDs later on, then remove this + .cond_where(Expr::col(KeyValueIden::Id).is_not_null()) .build_rusqlite(SqliteQueryBuilder); let mut stmt = self.conn.prepare(sql.as_str())?; let items = stmt.query_map(&*params.as_params(), KeyValue::from_row)?; From f5c3798df9514645e0391021d8511829eab9fdef Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 13 May 2025 10:35:02 -0700 Subject: [PATCH 169/996] Ability to disable proxy config Closes https://feedback.yaak.app/p/proxy-save-last-data --- src-tauri/src/http_request.rs | 9 ++- src-tauri/yaak-models/src/models.rs | 3 + src-web/components/Settings/SettingsProxy.tsx | 81 ++++++++++++++----- 3 files changed, 71 insertions(+), 22 deletions(-) diff --git a/src-tauri/src/http_request.rs b/src-tauri/src/http_request.rs index 82b84898b..1348d741c 100644 --- a/src-tauri/src/http_request.rs +++ b/src-tauri/src/http_request.rs @@ -123,7 +123,12 @@ pub async fn send_http_request( match settings.proxy { Some(ProxySetting::Disabled) => client_builder = client_builder.no_proxy(), - Some(ProxySetting::Enabled { http, https, auth }) => { + Some(ProxySetting::Enabled { + http, + https, + auth, + disabled, + }) if !disabled => { debug!("Using proxy http={http} https={https}"); let mut proxy = Proxy::custom(move |url| { let http = if http.is_empty() { None } else { Some(http.to_owned()) }; @@ -143,7 +148,7 @@ pub async fn send_http_request( client_builder = client_builder.proxy(proxy); } - None => {} // Nothing to do for this one, as it is the default + _ => {} // Nothing to do for this one, as it is the default } // Add cookie store if specified diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index 970ed1f94..607734d28 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -31,6 +31,9 @@ macro_rules! impl_model { #[ts(export, export_to = "gen_models.ts")] pub enum ProxySetting { Enabled { + #[serde(default)] + // This was added after on so give it a default to be able to deserialize older values + disabled: bool, http: String, https: String, auth: Option, diff --git a/src-web/components/Settings/SettingsProxy.tsx b/src-web/components/Settings/SettingsProxy.tsx index f6c9bf1ec..2c33f5c5e 100644 --- a/src-web/components/Settings/SettingsProxy.tsx +++ b/src-web/components/Settings/SettingsProxy.tsx @@ -24,6 +24,7 @@ export function SettingsProxy() { } else if (v === 'enabled') { await patchModel(settings, { proxy: { + disabled: false, type: 'enabled', http: '', https: '', @@ -42,16 +43,42 @@ export function SettingsProxy() { /> {settings.proxy?.type === 'enabled' && ( - + { + const { proxy } = settings; + const http = proxy?.type === 'enabled' ? proxy.http : ''; + const https = proxy?.type === 'enabled' ? proxy.https : ''; + const auth = proxy?.type === 'enabled' ? proxy.auth : null; + const disabled = !enabled; + await patchModel(settings, { + proxy: { type: 'enabled', http, https, auth, disabled }, + }); + }} + /> + { - const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : ''; - const auth = settings.proxy?.type === 'enabled' ? settings.proxy.auth : null; - await patchModel(settings, { proxy: { type: 'enabled', http, https, auth } }); + const { proxy } = settings; + const https = proxy?.type === 'enabled' ? proxy.https : ''; + const auth = proxy?.type === 'enabled' ? proxy.auth : null; + const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; + await patchModel(settings, { + proxy: { + type: 'enabled', + http, + https, + auth, + disabled, + }, + }); }} /> { - const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : ''; - const auth = settings.proxy?.type === 'enabled' ? settings.proxy.auth : null; - await patchModel(settings, { proxy: { type: 'enabled', http, https, auth } }); + const { proxy } = settings; + const http = proxy?.type === 'enabled' ? proxy.http : ''; + const auth = proxy?.type === 'enabled' ? proxy.auth : null; + const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; + await patchModel(settings, { + proxy: { type: 'enabled', http, https, auth, disabled }, + }); }} /> @@ -71,10 +102,14 @@ export function SettingsProxy() { checked={settings.proxy.auth != null} title="Enable authentication" onChange={async (enabled) => { - const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : ''; - const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : ''; + const { proxy } = settings; + const http = proxy?.type === 'enabled' ? proxy.http : ''; + const https = proxy?.type === 'enabled' ? proxy.https : ''; + const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; const auth = enabled ? { user: '', password: '' } : null; - await patchModel(settings, { proxy: { type: 'enabled', http, https, auth } }); + await patchModel(settings, { + proxy: { type: 'enabled', http, https, auth, disabled }, + }); }} /> @@ -87,12 +122,15 @@ export function SettingsProxy() { placeholder="myUser" defaultValue={settings.proxy.auth.user} onChange={async (user) => { - const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : ''; - const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : ''; - const password = - settings.proxy?.type === 'enabled' ? (settings.proxy.auth?.password ?? '') : ''; + const { proxy } = settings; + const http = proxy?.type === 'enabled' ? proxy.http : ''; + const https = proxy?.type === 'enabled' ? proxy.https : ''; + const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; + const password = proxy?.type === 'enabled' ? (proxy.auth?.password ?? '') : ''; const auth = { user, password }; - await patchModel(settings, { proxy: { type: 'enabled', http, https, auth } }); + await patchModel(settings, { + proxy: { type: 'enabled', http, https, auth, disabled }, + }); }} /> { - const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : ''; - const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : ''; - const user = - settings.proxy?.type === 'enabled' ? (settings.proxy.auth?.user ?? '') : ''; + const { proxy } = settings; + const http = proxy?.type === 'enabled' ? proxy.http : ''; + const https = proxy?.type === 'enabled' ? proxy.https : ''; + const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; + const user = proxy?.type === 'enabled' ? (proxy.auth?.user ?? '') : ''; const auth = { user, password }; - await patchModel(settings, { proxy: { type: 'enabled', http, https, auth } }); + await patchModel(settings, { + proxy: { type: 'enabled', http, https, auth, disabled }, + }); }} /> From e5070513ac7323f183f2b68e2ab5152f3d09f159 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 13 May 2025 10:45:41 -0700 Subject: [PATCH 170/996] Regenerate types --- src-tauri/yaak-models/bindings/gen_models.ts | 2 +- src-tauri/yaak-models/bindings/gen_util.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src-tauri/yaak-models/bindings/gen_models.ts b/src-tauri/yaak-models/bindings/gen_models.ts index 02e4fcf51..e59ed39f9 100644 --- a/src-tauri/yaak-models/bindings/gen_models.ts +++ b/src-tauri/yaak-models/bindings/gen_models.ts @@ -54,7 +54,7 @@ export type Plugin = { model: "plugin", id: string, createdAt: string, updatedAt export type PluginKeyValue = { model: "plugin_key_value", createdAt: string, updatedAt: string, pluginName: string, key: string, value: string, }; -export type ProxySetting = { "type": "enabled", http: string, https: string, auth: ProxySettingAuth | null, } | { "type": "disabled" }; +export type ProxySetting = { "type": "enabled", disabled: boolean, http: string, https: string, auth: ProxySettingAuth | null, } | { "type": "disabled" }; export type ProxySettingAuth = { user: string, password: string, }; diff --git a/src-tauri/yaak-models/bindings/gen_util.ts b/src-tauri/yaak-models/bindings/gen_util.ts index 482d19026..a38424de1 100644 --- a/src-tauri/yaak-models/bindings/gen_util.ts +++ b/src-tauri/yaak-models/bindings/gen_util.ts @@ -1,9 +1,9 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -import type { Environment } from "./gen_models.js"; -import type { Folder } from "./gen_models.js"; -import type { GrpcRequest } from "./gen_models.js"; -import type { HttpRequest } from "./gen_models.js"; -import type { WebsocketRequest } from "./gen_models.js"; -import type { Workspace } from "./gen_models.js"; +import type { Environment } from "./gen_models"; +import type { Folder } from "./gen_models"; +import type { GrpcRequest } from "./gen_models"; +import type { HttpRequest } from "./gen_models"; +import type { WebsocketRequest } from "./gen_models"; +import type { Workspace } from "./gen_models"; export type BatchUpsertResult = { workspaces: Array, environments: Array, folders: Array, httpRequests: Array, grpcRequests: Array, websocketRequests: Array, }; From 861609ddc03e07869f9d8456f2aede2298008452 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 13 May 2025 11:38:02 -0700 Subject: [PATCH 171/996] Update encryption help --- src-web/components/EncryptionHelp.tsx | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src-web/components/EncryptionHelp.tsx b/src-web/components/EncryptionHelp.tsx index 167997e30..e687dedff 100644 --- a/src-web/components/EncryptionHelp.tsx +++ b/src-web/components/EncryptionHelp.tsx @@ -1,14 +1,13 @@ -import {VStack} from "./core/Stacks"; +import { VStack } from './core/Stacks'; export function EncryptionHelp() { - return -

- Encrypt values like secrets and tokens. When enabled, Yaak will also encrypt HTTP responses, - cookies, and authentication credentials automatically. -

-

- Encrypted data remains secure when syncing to the filesystem or Git, and when exporting or - sharing with others. -

+ return ( + +

Encrypt passwords, tokens, and other sensitive info when encryption is enabled.

+

+ Encrypted data remains secure when syncing to the filesystem or Git, and when exporting or + sharing with others. +

+ ); } From 121fe5b3ea61906955cf4d3c7fb22096d0560fdb Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 13 May 2025 11:53:46 -0700 Subject: [PATCH 172/996] Fix help text --- src-web/components/WorkspaceEncryptionSetting.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src-web/components/WorkspaceEncryptionSetting.tsx b/src-web/components/WorkspaceEncryptionSetting.tsx index 8373c8555..07c1e264c 100644 --- a/src-web/components/WorkspaceEncryptionSetting.tsx +++ b/src-web/components/WorkspaceEncryptionSetting.tsx @@ -250,8 +250,8 @@ function HighlightedKey({ keyText, show }: { keyText: string; show: boolean }) { const helpAfterEncryption = (

- this key is used for any encryption used for this workspace. It is stored securely using your OS - keychain, but it is recommended to back it up. If you share this workspace with others, - you'll need to send them this key to access any encrypted values. + The following key is used for encryption operations within this workspace. It is stored securely + using your OS keychain, but it is recommended to back it up. If you share this workspace with + others, you'll need to send them this key to access any encrypted values.

); From bc4c3178c99fa1d47f4481e06cd32b2dd5f914fb Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 13 May 2025 21:58:00 -0700 Subject: [PATCH 173/996] Add Content-Length: 0 default for post/put/patch https://feedback.yaak.app/p/missing-content-length --- src-tauri/src/http_request.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src-tauri/src/http_request.rs b/src-tauri/src/http_request.rs index 1348d741c..0b38c0c85 100644 --- a/src-tauri/src/http_request.rs +++ b/src-tauri/src/http_request.rs @@ -399,6 +399,15 @@ pub async fn send_http_request( } else { warn!("Unsupported body type: {}", body_type); } + } else { + // No body set + let method = request.method.to_ascii_lowercase(); + let is_body_method = method == "post" || method == "put" || method == "patch"; + // Add Content-Length for methods that commonly accept a body because some servers + // will error if they don't receive it. + if is_body_method && !headers.contains_key("content-length") { + headers.insert("Content-Length", HeaderValue::from_static("0")); + } } // Add headers last, because previous steps may modify them From cbc40230bb76bee725b7960f7d2cedc125121684 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 14 May 2025 20:05:04 -0700 Subject: [PATCH 174/996] Fix cursor position after variable on Linux Closes https://feedback.yaak.app/p/editing-the-url-sometimes-freezes-the-app --- src-tauri/yaak-models/guest-js/store.ts | 3 ++- src-tauri/yaak-models/src/commands.rs | 35 +++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src-tauri/yaak-models/guest-js/store.ts b/src-tauri/yaak-models/guest-js/store.ts index b1d30fd6a..5514683e8 100644 --- a/src-tauri/yaak-models/guest-js/store.ts +++ b/src-tauri/yaak-models/guest-js/store.ts @@ -53,9 +53,10 @@ let _activeWorkspaceId: string | null = null; export async function changeModelStoreWorkspace(workspaceId: string | null) { console.log('Syncing models with new workspace', workspaceId); - const workspaceModels = await invoke('plugin:yaak-models|workspace_models', { + const workspaceModelsStr = await invoke('plugin:yaak-models|workspace_models', { workspaceId, // NOTE: if no workspace id provided, it will just fetch global models }); + const workspaceModels = JSON.parse(workspaceModelsStr) as AnyModel[]; const data = newStoreData(); for (const model of workspaceModels) { data[model.model][model.id] = model; diff --git a/src-tauri/yaak-models/src/commands.rs b/src-tauri/yaak-models/src/commands.rs index 3e75d0de5..ff5124d47 100644 --- a/src-tauri/yaak-models/src/commands.rs +++ b/src-tauri/yaak-models/src/commands.rs @@ -94,7 +94,7 @@ pub(crate) fn get_settings(app_handle: AppHandle) -> Result( window: WebviewWindow, workspace_id: Option<&str>, -) -> Result> { +) -> Result { let db = window.db(); let mut l: Vec = Vec::new(); @@ -120,5 +120,36 @@ pub(crate) fn workspace_models( l.append(&mut db.list_workspace_metas(wid)?.into_iter().map(Into::into).collect()); } - Ok(l) + let j = serde_json::to_string(&l)?; + + // NOTE: There's something weird that happens on Linux. If we send Cyrillic (or maybe other) + // unicode characters in this response (doesn't matter where) then the following bug happens: + // https://feedback.yaak.app/p/editing-the-url-sometimes-freezes-the-app + // + // It's as if every string resulting from the JSON.parse of the models gets encoded slightly + // wrong or something, causing the above bug where Codemirror can't calculate the cursor + // position anymore (even when none of the characters are included directly in the input). + // + // For some reason using escape sequences works, but it's a hacky fix. Hopefully the Linux + // webview dependency updates to a version where this bug doesn't exist, or we can use CEF + // (Chromium) for Linux in the future, which Tauri is working on. + Ok(escape_str_for_webview(&j)) } + +fn escape_str_for_webview(input: &str) -> String { + input.chars().map(|c| { + let code = c as u32; + // ASCII + if code <= 0x7F { + c.to_string() + // BMP characters encoded normally + } else if code < 0xFFFF { + format!("\\u{:04X}", code) + // Beyond BMP encoded a surrogate pairs + } else { + let high = ((code - 0x10000) >> 10) + 0xD800; + let low = ((code - 0x10000) & 0x3FF) + 0xDC00; + format!("\\u{:04X}\\u{:04X}", high, low) + } + }).collect() +} \ No newline at end of file From 8a7a7ba49d41d7eb02fdf668e306c1594294634b Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 14 May 2025 20:43:59 -0700 Subject: [PATCH 175/996] Try fixing trusted-signing-cli --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7f2532fac..ea8d8514b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,7 +65,7 @@ jobs: - name: install dependencies (windows only) if: matrix.platform == 'windows-latest' - run: cargo install --force trusted-signing-cli + run: cargo install --force trusted-signing-cli --version 0.5.0 - name: Install NPM Dependencies run: | From c18843552490769fd37202a153a3484671c79c28 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 15 May 2025 07:00:25 -0700 Subject: [PATCH 176/996] Fix obscured text overflow https://feedback.yaak.app/p/pasting-token-auth-results-in-invisible-text --- src-web/components/core/Editor/Editor.css | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src-web/components/core/Editor/Editor.css b/src-web/components/core/Editor/Editor.css index 35d96d15e..5a6003f25 100644 --- a/src-web/components/core/Editor/Editor.css +++ b/src-web/components/core/Editor/Editor.css @@ -102,11 +102,13 @@ } .cm-scroller { - @apply font-mono text-xs overflow-hidden; - } + @apply font-mono text-xs; - .cm-line { - @apply overflow-hidden; + /* Hide scrollbars */ + &::-webkit-scrollbar-corner, + &::-webkit-scrollbar { + @apply hidden !important; + } } } From 21e2a67c1eb704310459aeaa2575a1200ca7471c Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 15 May 2025 07:10:08 -0700 Subject: [PATCH 177/996] Fix sidebar scroll drag https://feedback.yaak.app/p/endpoinst-scrollbar-not-clickable --- src-web/components/ResizeHandle.tsx | 4 ++-- src-web/components/Workspace.tsx | 2 +- src-web/components/core/Checkbox.tsx | 10 ++++++---- src-web/components/core/PairEditor.tsx | 22 +++++++++++----------- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src-web/components/ResizeHandle.tsx b/src-web/components/ResizeHandle.tsx index 1b204539a..027b4275d 100644 --- a/src-web/components/ResizeHandle.tsx +++ b/src-web/components/ResizeHandle.tsx @@ -32,8 +32,8 @@ export function ResizeHandle({ className={classNames( className, 'group z-10 flex select-none', - // 'bg-fg-info', // For debugging - vertical ? 'w-full h-3 cursor-row-resize' : 'h-full w-3 cursor-col-resize', + // 'bg-info', // For debugging + vertical ? 'w-full h-2 cursor-row-resize' : 'h-full w-2 cursor-col-resize', justify === 'center' && 'justify-center', justify === 'end' && 'justify-end', justify === 'start' && 'justify-start', diff --git a/src-web/components/Workspace.tsx b/src-web/components/Workspace.tsx index 5d49623c7..838f483b0 100644 --- a/src-web/components/Workspace.tsx +++ b/src-web/components/Workspace.tsx @@ -163,7 +163,7 @@ export function Workspace() {
@@ -56,9 +56,11 @@ export function Checkbox({ />
-
- {!hideLabel && title} -
+ {!hideLabel && ( +
+ {title} +
+ )} {help && } ); diff --git a/src-web/components/core/PairEditor.tsx b/src-web/components/core/PairEditor.tsx index 56a7da2ec..ff15e2c08 100644 --- a/src-web/components/core/PairEditor.tsx +++ b/src-web/components/core/PairEditor.tsx @@ -221,7 +221,7 @@ export const PairEditor = forwardRef(function Pa 'pb-2 mb-auto h-full', !noScroll && 'overflow-y-auto max-h-full', // Move over the width of the drag handle - '-ml-3 -mr-2 pr-2', + '-mr-2 pr-2', // Pad to make room for the drag divider 'pt-0.5', )} @@ -458,26 +458,26 @@ function PairEditorRow({ !pair.enabled && 'opacity-60', )} > + {!isLast ? (
) : ( - + )} -
Date: Thu, 15 May 2025 09:28:14 -0700 Subject: [PATCH 178/996] remove codemirror dep and restructure a bit --- package-lock.json | 2509 ++--------------- .../{openSettings.ts => openSettings.tsx} | 5 +- src-web/components/GraphQLEditor.tsx | 4 +- src-web/components/GrpcEditor.tsx | 2 +- src-web/components/HttpRequestPane.tsx | 11 +- src-web/components/HttpResponsePane.tsx | 7 +- src-web/components/LicenseBadge.tsx | 5 +- src-web/components/Settings/Settings.tsx | 27 +- src-web/components/Settings/SettingsTab.ts | 8 - src-web/components/SettingsDropdown.tsx | 3 +- src-web/components/UrlBar.tsx | 4 +- src-web/components/Workspace.tsx | 10 +- src-web/components/core/Editor/Editor.tsx | 114 +- src-web/components/core/Editor/extensions.ts | 37 +- .../core/Editor/hyperlink/extension.ts | 3 +- .../core/Editor/twig/pathParameters.ts | 3 +- .../core/Editor/twig/templateTags.ts | 3 +- src-web/components/core/Input.tsx | 2 +- src-web/components/core/PairEditor.tsx | 2 +- .../components/responseViewers/PdfViewer.tsx | 7 + src-web/main.tsx | 7 - src-web/package.json | 28 +- src-web/routes/__root.tsx | 22 - .../workspaces/$workspaceId/settings.tsx | 14 +- src-web/vite.config.ts | 10 +- 25 files changed, 394 insertions(+), 2453 deletions(-) rename src-web/commands/{openSettings.ts => openSettings.tsx} (87%) delete mode 100644 src-web/components/Settings/SettingsTab.ts diff --git a/package-lock.json b/package-lock.json index bac94ce34..63ee37488 100644 --- a/package-lock.json +++ b/package-lock.json @@ -473,9 +473,9 @@ } }, "node_modules/@codemirror/commands": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.7.0.tgz", - "integrity": "sha512-+cduIZ2KbesDhbykV02K25A5xIVrquSPz4UxxYBemRlAT2aW8dhwUgLDwej7q/RJUHKk4nALYcR1puecDvbdqw==", + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz", + "integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", @@ -515,9 +515,9 @@ } }, "node_modules/@codemirror/lang-javascript": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz", - "integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==", + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.4.tgz", + "integrity": "sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.0.0", @@ -540,9 +540,9 @@ } }, "node_modules/@codemirror/lang-markdown": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.3.1.tgz", - "integrity": "sha512-y3sSPuQjBKZQbQwe3ZJKrSW6Silyl9PnrU/Mf0m2OQgIlPoSYTtOvEL7xs94SVMkb8f4x+SQFnzXPdX4Wk2lsg==", + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.3.2.tgz", + "integrity": "sha512-c/5MYinGbFxYl4itE9q/rgN/sMTjOr8XL5OWnC+EaRMLfCbVUmmubTJfdgpfcSS2SCaT7b+Q+xi3l6CgoE+BsA==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.7.1", @@ -569,9 +569,9 @@ } }, "node_modules/@codemirror/language": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.3.tgz", - "integrity": "sha512-kDqEU5sCP55Oabl6E7m5N+vZRoc0iWqgDVhEKifcHzPzjqCegcO4amfrYVL9PmPZpl4G0yjkpTpUO/Ui8CzO8A==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.0.tgz", + "integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", @@ -594,9 +594,9 @@ } }, "node_modules/@codemirror/search": { - "version": "6.5.6", - "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz", - "integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==", + "version": "6.5.11", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.11.tgz", + "integrity": "sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", @@ -667,38 +667,6 @@ "postcss-selector-parser": "^6.1.0" } }, - "node_modules/@electron/get": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", - "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "got": "^11.8.5", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "global-agent": "^3.0.0" - } - }, - "node_modules/@electron/get/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", @@ -1665,16 +1633,16 @@ } }, "node_modules/@replit/codemirror-vim": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@replit/codemirror-vim/-/codemirror-vim-6.2.1.tgz", - "integrity": "sha512-qDAcGSHBYU5RrdO//qCmD8K9t6vbP327iCj/iqrkVnjbrpFhrjOt92weGXGHmTNRh16cUtkUZ7Xq7rZf+8HVow==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@replit/codemirror-vim/-/codemirror-vim-6.3.0.tgz", + "integrity": "sha512-aTx931ULAMuJx6xLf7KQDOL7CxD+Sa05FktTDrtLaSy53uj01ll3Zf17JdKsriER248oS55GBzg0CfCTjEneAQ==", "license": "MIT", "peerDependencies": { - "@codemirror/commands": "^6.0.0", - "@codemirror/language": "^6.1.0", - "@codemirror/search": "^6.2.0", - "@codemirror/state": "^6.0.1", - "@codemirror/view": "^6.0.3" + "@codemirror/commands": "6.x.x", + "@codemirror/language": "6.x.x", + "@codemirror/search": "6.x.x", + "@codemirror/state": "6.x.x", + "@codemirror/view": "6.x.x" } }, "node_modules/@replit/codemirror-vscode-keymap": { @@ -2049,19 +2017,6 @@ "ebnf": "^1.9.1" } }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", @@ -2526,19 +2481,6 @@ "@swc/counter": "^0.1.3" } }, - "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@tailwindcss/container-queries": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz", @@ -2562,9 +2504,9 @@ } }, "node_modules/@tanstack/history": { - "version": "1.99.13", - "resolved": "https://registry.npmjs.org/@tanstack/history/-/history-1.99.13.tgz", - "integrity": "sha512-JMd7USmnp8zV8BRGIjALqzPxazvKtQ7PGXQC7n39HpbqdsmfV2ePCzieO84IvN+mwsTrXErpbjI4BfKCa+ZNCg==", + "version": "1.115.0", + "resolved": "https://registry.npmjs.org/@tanstack/history/-/history-1.115.0.tgz", + "integrity": "sha512-K7JJNrRVvyjAVnbXOH2XLRhFXDkeP54Kt2P4FR1Kl2KDGlIbkua5VqZQD2rot3qaDrpufyUa63nuLai1kOLTsQ==", "license": "MIT", "engines": { "node": ">=12" @@ -2575,20 +2517,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.66.4", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.66.4.tgz", - "integrity": "sha512-skM/gzNX4shPkqmdTCSoHtJAPMTtmIJNS0hE+xwTTUVYwezArCT34NMermABmBVUg5Ls5aiUXEDXfqwR1oVkcA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tanstack/query-devtools": { - "version": "5.61.4", - "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.61.4.tgz", - "integrity": "sha512-21Tw+u8E3IJJj4A/Bct4H0uBaDTEu7zBrR79FeSyY+mS2gx5/m316oDtJiKkILc819VSTYt+sFzODoJNcpPqZQ==", - "dev": true, + "version": "5.76.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.76.0.tgz", + "integrity": "sha512-FN375hb8ctzfNAlex5gHI6+WDXTNpe0nbxp/d2YJtnP+IBM6OUm7zcaoCW6T63BawGOYZBbKC0iPvr41TteNVg==", "license": "MIT", "funding": { "type": "github", @@ -2596,48 +2527,30 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.66.9", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.66.9.tgz", - "integrity": "sha512-NRI02PHJsP5y2gAuWKP+awamTIBFBSKMnO6UVzi03GTclmHHHInH5UzVgzi5tpu4+FmGfsdT7Umqegobtsp23A==", - "license": "MIT", - "dependencies": { - "@tanstack/query-core": "5.66.4" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^18 || ^19" - } - }, - "node_modules/@tanstack/react-query-devtools": { - "version": "5.62.8", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.62.8.tgz", - "integrity": "sha512-SwjXjQTRONd9WPeKVQQ9framG7YNqPV8PS+EGNVNXAyz2XThulMRCvZnh2+3DggnjcYM7YcpnuoZ4RH7q13p0g==", - "dev": true, + "version": "5.76.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.76.1.tgz", + "integrity": "sha512-YxdLZVGN4QkT5YT1HKZQWiIlcgauIXEIsMOTSjvyD5wLYK8YVvKZUPAysMqossFJJfDpJW3pFn7WNZuPOqq+fw==", "license": "MIT", "dependencies": { - "@tanstack/query-devtools": "5.61.4" + "@tanstack/query-core": "5.76.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "@tanstack/react-query": "^5.62.8", "react": "^18 || ^19" } }, "node_modules/@tanstack/react-router": { - "version": "1.111.3", - "resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.111.3.tgz", - "integrity": "sha512-OsqAuExa4WF7+BbjENWlb4dHRousxU5jahJHUPyO0gaUcWwzaVloJKi8lTFTd1PWQ8waz5V7BedkV67hd8syUw==", + "version": "1.120.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.120.3.tgz", + "integrity": "sha512-+5Y5ORtjW/LJhIxOxxBrvhZzfMOP9B+LaJ1j1P5tM5YqpLYWHuImfzGNRpKtBgiRoSaJedPjwY7lj88EwNWVbg==", "license": "MIT", "dependencies": { - "@tanstack/history": "1.99.13", + "@tanstack/history": "1.115.0", "@tanstack/react-store": "^0.7.0", - "@tanstack/router-core": "^1.111.3", + "@tanstack/router-core": "1.120.3", "jsesc": "^3.1.0", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" @@ -2673,12 +2586,12 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.0.tgz", - "integrity": "sha512-CchF0NlLIowiM2GxtsoKBkXA4uqSnY2KvnXo+kyUFD4a4ll6+J0qzoRsUPMwXV/H26lRsxgJIr/YmjYum2oEjg==", + "version": "3.13.8", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.8.tgz", + "integrity": "sha512-meS2AanUg50f3FBSNoAdBSRAh8uS0ue01qm7zrw65KGJtiXB9QXfybqZwkh4uFpRv2iX/eu5tjcH5wqUpwYLPg==", "license": "MIT", "dependencies": { - "@tanstack/virtual-core": "3.13.0" + "@tanstack/virtual-core": "3.13.8" }, "funding": { "type": "github", @@ -2690,31 +2603,14 @@ } }, "node_modules/@tanstack/router-core": { - "version": "1.111.3", - "resolved": "https://registry.npmjs.org/@tanstack/router-core/-/router-core-1.111.3.tgz", - "integrity": "sha512-q+CHuOhTgqHudVKijL89jIdLe5A00RzV8ZMMSi4qiHGnggm4nisF8eSE3dFQaic1+YFk1wR7dfFA2hvkr1hFIA==", - "license": "MIT", - "dependencies": { - "@tanstack/history": "1.99.13", - "@tanstack/store": "^0.7.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tanstack/router-devtools": { - "version": "1.91.3", - "resolved": "https://registry.npmjs.org/@tanstack/router-devtools/-/router-devtools-1.91.3.tgz", - "integrity": "sha512-b/WOhWEC7+Znh0+OrSGxl7RMCwHT5vX6fygDN1wh1yiUOjs32EJquu4c9deWzRDlF3jV6ji7XYWs1XgKXcsrww==", - "dev": true, + "version": "1.120.3", + "resolved": "https://registry.npmjs.org/@tanstack/router-core/-/router-core-1.120.3.tgz", + "integrity": "sha512-/16Pp7yxUUIGkc+oPVnlWqvlGtvLoQeKfJPpKc1vcPIBvHFO/o3yg/CEzP5raWDAjyq3b+BVkej3lSzkNxgBSg==", "license": "MIT", "dependencies": { - "clsx": "^2.1.1", - "goober": "^2.1.16" + "@tanstack/history": "1.115.0", + "@tanstack/store": "^0.7.0", + "tiny-invariant": "^1.3.3" }, "engines": { "node": ">=12" @@ -2722,11 +2618,6 @@ "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "@tanstack/react-router": "^1.91.3", - "react": ">=18", - "react-dom": ">=18" } }, "node_modules/@tanstack/router-generator": { @@ -2810,9 +2701,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.0.tgz", - "integrity": "sha512-NBKJP3OIdmZY3COJdWkSonr50FMVIi+aj5ZJ7hI/DTpEKg2RMfo/KvP8A3B/zOSpMgIe52B5E2yn7rryULzA6g==", + "version": "3.13.8", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.8.tgz", + "integrity": "sha512-BT6w89Hqy7YKaWewYzmecXQzcJh6HTBbKYJIIkMaNU49DZ06LoTV3z32DWWEdUsgW6n1xTmwTLs4GtWrZC261w==", "license": "MIT", "funding": { "type": "github", @@ -3168,19 +3059,6 @@ "@babel/types": "^7.20.7" } }, - "node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -3214,13 +3092,6 @@ "@types/unist": "*" } }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/js-cookie": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", @@ -3240,16 +3111,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -3324,16 +3185,6 @@ "@types/react": "*" } }, - "node_modules/@types/responselike": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", - "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -3364,17 +3215,6 @@ "@types/node": "*" } }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.27.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.27.0.tgz", @@ -3733,63 +3573,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha512-TdlOggdA/zURfMYa7ABC66j+oqfMew58KpJMbUlH3bcZP1b+cBHIHDDn5uH9INsxrHBPjsqM0tDB4jPTF/vgJA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^2.0.0" - } - }, - "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -4265,262 +4048,110 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/boxen": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", - "dev": true, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "license": "MIT", "dependencies": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - }, - "engines": { - "node": ">=4" + "balanced-match": "^1.0.0" } }, - "node_modules/boxen/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/boxen/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/browserslist": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" }, "engines": { - "node": ">=4" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/boxen/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "node_modules/boxen/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" } }, - "node_modules/boxen/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", "dev": true, "license": "MIT" }, - "node_modules/boxen/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/boxen/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001663", - "electron-to-chromium": "^1.5.28", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "node_modules/buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true, - "license": "MIT" - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" + "node": "*" } }, "node_modules/buffer-fill": { @@ -4530,51 +4161,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -4633,16 +4219,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", @@ -4689,19 +4265,6 @@ "node": ">=6" } }, - "node_modules/capture-stack-trace": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.2.tgz", - "integrity": "sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -4815,13 +4378,6 @@ "node": ">=10" } }, - "node_modules/ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true, - "license": "MIT" - }, "node_modules/cidr-regex": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/cidr-regex/-/cidr-regex-4.0.3.tgz", @@ -4886,16 +4442,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -4923,19 +4469,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -4946,110 +4479,47 @@ } }, "node_modules/cm6-graphql": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/cm6-graphql/-/cm6-graphql-0.0.9.tgz", - "integrity": "sha512-MhdQMuVGwnyEk3I1BiLhpMEhOC7sTxmbq205cjdDtHysB0EtNLBoccy+7+h/+So90otjwJcSaty6vwp22WN6kw==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cm6-graphql/-/cm6-graphql-0.2.1.tgz", + "integrity": "sha512-FIAFHn6qyiXChTz3Pml0NgTM8LyyXs8QfP2iPG7MLA8Xi83WuVlkGG5PDs+DDeEVabHkLIZmcyNngQlxLXKk6A==", "license": "MIT", "dependencies": { - "graphql-language-service": "^5.1.7" + "graphql-language-service": "^5.3.0" }, "peerDependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.0.0", "@codemirror/lint": "^6.0.0", - "@codemirror/state": "^6.1.0", - "@codemirror/view": "^6.1.2", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", "@lezer/highlight": "^1.0.0", - "graphql": "^16.5.0" + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/codemirror": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", - "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "node_modules/codemirror-json5": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/codemirror-json5/-/codemirror-json5-1.0.3.tgz", + "integrity": "sha512-HmmoYO2huQxoaoG5ARKjqQc9mz7/qmNPvMbISVfIE2Gk1+4vZQg9X3G6g49MYM5IK00Ol3aijd7OKrySuOkA7Q==", "license": "MIT", + "optional": true, "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/commands": "^6.0.0", "@codemirror/language": "^6.0.0", - "@codemirror/lint": "^6.0.0", - "@codemirror/search": "^6.0.0", "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0" + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "json5": "^2.2.1", + "lezer-json5": "^2.0.2" } }, - "node_modules/codemirror-json-schema": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/codemirror-json-schema/-/codemirror-json-schema-0.6.1.tgz", - "integrity": "sha512-QG12Jy917eStZzxurpAE9QUQxF8SS/AYJ9DDteyJZcRGH8ePaBCfQ4KLCNtY6cUKjFeNBgcd5+c6FPAri6pPQg==", + "node_modules/codemirror-json5/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "license": "MIT", - "dependencies": { - "@changesets/changelog-github": "^0.4.8", - "@sagold/json-pointer": "^5.1.1", - "@types/json-schema": "^7.0.12", - "@types/node": "^20.4.2", - "json-schema": "^0.4.0", - "json-schema-library": "^9.1.2" - }, - "optionalDependencies": { - "@codemirror/lang-json": "^6.0.1", - "codemirror-json5": "^1.0.3", - "json5": "^2.2.3" - }, - "peerDependencies": { - "@codemirror/language": "^6.8.0", - "@codemirror/lint": "^6.4.0", - "@codemirror/state": "^6.2.1", - "@codemirror/view": "^6.14.1", - "@lezer/common": "^1.0.3" - } - }, - "node_modules/codemirror-json-schema/node_modules/@types/node": { - "version": "20.16.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", - "integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/codemirror-json-schema/node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "license": "MIT", - "optional": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/codemirror-json5": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/codemirror-json5/-/codemirror-json5-1.0.3.tgz", - "integrity": "sha512-HmmoYO2huQxoaoG5ARKjqQc9mz7/qmNPvMbISVfIE2Gk1+4vZQg9X3G6g49MYM5IK00Ol3aijd7OKrySuOkA7Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.0.0", - "@lezer/highlight": "^1.0.0", - "json5": "^2.2.1", - "lezer-json5": "^2.0.2" - } - }, - "node_modules/codemirror-json5/node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "license": "MIT", - "optional": true, - "bin": { - "json5": "lib/cli.js" + "optional": true, + "bin": { + "json5": "lib/cli.js" }, "engines": { "node": ">=6" @@ -5106,24 +4576,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/configstore": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.5.tgz", - "integrity": "sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dot-prop": "^4.2.1", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -5284,19 +4736,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "capture-stack-trace": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/crelt": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", @@ -5316,16 +4755,6 @@ "node": ">= 8" } }, - "node_modules/crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/css-in-js-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", @@ -5508,35 +4937,6 @@ "node": ">=4" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/decompress-tar": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", @@ -5672,16 +5072,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -5711,16 +5101,6 @@ "node": ">= 16" } }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -5781,14 +5161,6 @@ "node": ">=8" } }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/devlop": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", @@ -5878,19 +5250,6 @@ "tslib": "^2.0.3" } }, - "node_modules/dot-prop": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz", - "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-obj": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/dotenv": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", @@ -5914,13 +5273,6 @@ "node": ">= 0.4" } }, - "node_modules/duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -5936,25 +5288,6 @@ "ebnf": "dist/bin.js" } }, - "node_modules/electron": { - "version": "23.3.13", - "resolved": "https://registry.npmjs.org/electron/-/electron-23.3.13.tgz", - "integrity": "sha512-BaXtHEb+KYKLouUXlUVDa/lj9pj4F5kiE0kwFdJV84Y2EU7euIDgPthfKtchhr5MVHmjtavRMIV/zAwEiSQ9rQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@electron/get": "^2.0.0", - "@types/node": "^16.11.26", - "extract-zip": "^2.0.1" - }, - "bin": { - "electron": "cli.js" - }, - "engines": { - "node": ">= 12.20.55" - } - }, "node_modules/electron-to-chromium": { "version": "1.5.34", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.34.tgz", @@ -5962,13 +5295,6 @@ "dev": true, "license": "ISC" }, - "node_modules/electron/node_modules/@types/node": { - "version": "16.18.113", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.113.tgz", - "integrity": "sha512-4jHxcEzSXpF1cBNxogs5FVbVSFSKo50sFCn7Xg7vmjJTbWFWgeuHW3QnoINlfmfG++MFR/q97RZE5RQXKeT+jg==", - "dev": true, - "license": "MIT" - }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -5998,16 +5324,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -6207,14 +5523,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/esbuild": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", @@ -6881,43 +6189,6 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/fast-copy": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", @@ -7230,21 +6501,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -7536,38 +6792,6 @@ "node": "*" } }, - "node_modules/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "^1.3.4" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -7621,16 +6845,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/goober": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", - "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "csstype": "^3.0.10" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -7643,32 +6857,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -7887,27 +7075,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -7985,16 +7152,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -8037,13 +7194,6 @@ "devOptional": true, "license": "ISC" }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, "node_modules/inline-style-parser": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", @@ -8124,16 +7274,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/is-alphabetical": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", @@ -8265,19 +7405,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ci-info": "^1.5.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, "node_modules/is-core-module": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", @@ -8403,33 +7530,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha512-ERNhMg+i/XgDwPIPF3u24qpajVreaiSuvpb1Uu0jugw7KKcxGyCX8cgp8P5fwTmAuXku6beDHHECdKArjlg7tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/is-installed-globally/node_modules/is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-is-inside": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-ip": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-5.0.1.tgz", @@ -8479,16 +7579,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha512-9r39FIr3d+KD9SbX0sfMsHzb5PP3uimOiwr3YupUaUFG4W0l1U57Rx3utpttV7qz5U3jmrO5auUa04LU9pyHsg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -8513,16 +7603,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -8545,16 +7625,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -8584,16 +7654,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-set": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", @@ -8891,14 +7951,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC", - "optional": true - }, "node_modules/json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", @@ -8912,16 +7964,6 @@ "json5": "lib/cli.js" } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -8981,19 +8023,6 @@ "node": ">=0.10" } }, - "node_modules/latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha512-Be1YRHWWlZaSsrz2U+VInk+tO0EwLIyV+23RhWLINJYwg/UIikxjlj3MhH37/6/EDCAusjajvMkMMUXRaMWl/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "package-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -9104,16 +8133,6 @@ "tslib": "^2.0.3" } }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -9174,20 +8193,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -10167,16 +9172,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -10519,19 +9514,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/npm-run-all": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", @@ -10965,16 +9947,6 @@ "node": ">= 0.8.0" } }, - "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/p-event": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", @@ -11023,16 +9995,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -11100,81 +10062,12 @@ "node": ">=6" } }, - "node_modules/package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha512-q/R5GrMek0vzgoomq6rm9OX+3PQve8sLwTirmK30YB3Cu0Bbt9OX9M/SIUnroN5BGJkzwGsFwDaRGD9EwBOlCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, - "node_modules/package-json/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/package-json/node_modules/got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha512-Y/K3EDuiQN9rTZhBvPRWMLXIKdeD1Rj0nzunfoi0Yyn5WBEbzxXKU9Ub2X41oZBagVWOBU3MuDonFMgPWQFnwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/package-json/node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/package-json/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/papaparse": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz", @@ -11266,13 +10159,6 @@ "node": ">=0.10.0" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true, - "license": "(WTFPL OR MIT)" - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -11623,16 +10509,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/prettier": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", @@ -11656,16 +10532,6 @@ "dev": true, "license": "MIT" }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -11687,24 +10553,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -11735,19 +10583,6 @@ ], "license": "MIT" }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/railroad-diagrams": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", @@ -11755,397 +10590,30 @@ "license": "CC0-1.0" }, "node_modules/randexp": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", - "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", - "license": "MIT", - "dependencies": { - "discontinuous-range": "1.0.0", - "ret": "~0.1.10" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-devtools": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/react-devtools/-/react-devtools-5.3.1.tgz", - "integrity": "sha512-RcSV/u+lPChcTB+A4fij0xkE204yzKdAsGUFy6+DrfUzWSawB+cu0n3WLmJcJXQ/VnmjSUlIrqmVLicRhT/gLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^5.0.1", - "electron": "^23.1.2", - "internal-ip": "^6.2.0", - "minimist": "^1.2.3", - "react-devtools-core": "5.3.1", - "update-notifier": "^2.1.0" - }, - "bin": { - "react-devtools": "bin.js" - } - }, - "node_modules/react-devtools-core": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-5.3.1.tgz", - "integrity": "sha512-7FSb9meX0btdBQLwdFOwt6bGqvRPabmVMMslv8fgoSPqXyuGpgQe36kx8gR86XPw7aV1yVouTp6fyZ0EH+NfUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "shell-quote": "^1.6.1", - "ws": "^7" - } - }, - "node_modules/react-devtools/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/react-devtools/node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/react-devtools/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/react-devtools/node_modules/execa/node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/react-devtools/node_modules/execa/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-devtools/node_modules/execa/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-devtools/node_modules/execa/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/react-devtools/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-devtools/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/react-devtools/node_modules/internal-ip": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", - "integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==", - "dev": true, - "license": "MIT", - "dependencies": { - "default-gateway": "^6.0.0", - "ipaddr.js": "^1.9.1", - "is-ip": "^3.1.0", - "p-event": "^4.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/internal-ip?sponsor=1" - } - }, - "node_modules/react-devtools/node_modules/ip-regex": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", - "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-devtools/node_modules/is-ip": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", - "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ip-regex": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-devtools/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-devtools/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/react-devtools/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/react-devtools/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-devtools/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-devtools/node_modules/p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-timeout": "^3.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-devtools/node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", "license": "MIT", "dependencies": { - "p-finally": "^1.0.0" + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" }, "engines": { - "node": ">=8" + "node": ">=0.12" } }, - "node_modules/react-devtools/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", "dependencies": { - "shebang-regex": "^1.0.0" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/react-devtools/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-devtools/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/react-devtools/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/react-devtools/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true, - "license": "ISC" - }, "node_modules/react-dnd": { "version": "16.0.1", "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz", @@ -12439,30 +10907,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/registry-auth-token": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", - "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "rc": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/remark-gfm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", @@ -12567,13 +11011,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true, - "license": "MIT" - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -12594,19 +11031,6 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -12643,25 +11067,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/rollup": { "version": "4.40.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz", @@ -12757,7 +11162,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "devOptional": true, "funding": [ { "type": "github", @@ -12772,7 +11176,8 @@ "url": "https://feross.org/support" } ], - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/safe-regex-test": { "version": "1.0.3", @@ -12850,68 +11255,6 @@ "node": ">=10" } }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^5.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/semver-diff/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -13243,14 +11586,6 @@ "dev": true, "license": "CC0-1.0" }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true - }, "node_modules/stack-generator": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", @@ -13550,16 +11885,6 @@ "is-natural-number": "^4.0.1" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -13667,19 +11992,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "debug": "^4.1.0" - }, - "engines": { - "node": ">= 8.0" - } - }, "node_modules/super-regex": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-0.2.0.tgz", @@ -13861,156 +12173,25 @@ "node_modules/tar-stream/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/tar-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true, - "license": "ISC" - }, - "node_modules/term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha512-7dPUZQGy/+m3/wjVz3ZW5dobSoD/02NxJpoXUX0WIyjfVS3l0c+b/+9phIDFA7FHzkYtwtMFgeGZ/Y8jVTeqQQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^0.7.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/term-size/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/term-size/node_modules/execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/term-size/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/term-size/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/term-size/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/term-size/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/term-size/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/term-size/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" }, - "node_modules/term-size/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/tar-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" + "safe-buffer": "~5.1.0" } }, - "node_modules/term-size/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "devOptional": true, "license": "ISC" }, "node_modules/text-table": { @@ -14073,16 +12254,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", @@ -14845,19 +13016,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "crypto-random-string": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", @@ -14926,16 +13084,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unplugin": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.0.tgz", @@ -14950,16 +13098,6 @@ "node": ">=14.0.0" } }, - "node_modules/unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha512-N0XH6lqDtFH84JxptQoZYmloF4nzrQqqrAymNj+/gW60AO2AZgOcf4O/nUXJcYfyQkqvMo9lSupBZmmgvuVXlw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/update-browserslist-db": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", @@ -14991,106 +13129,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/update-notifier": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/update-notifier/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/update-notifier/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/update-notifier/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/update-notifier/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/update-notifier/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/update-notifier/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -15101,19 +13139,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "prepend-http": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/use-sync-external-store": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz", @@ -15541,66 +13566,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "node_modules/widest-line": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", - "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^2.1.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -15650,50 +13615,6 @@ "devOptional": true, "license": "ISC" }, - "node_modules/write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/xml-formatter": { "version": "3.6.3", "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-3.6.3.tgz", @@ -15905,7 +13826,7 @@ }, "packages/plugin-runtime-types": { "name": "@yaakapp/api", - "version": "0.5.0", + "version": "0.5.3", "dependencies": { "@types/node": "^22.5.4" }, @@ -16044,23 +13965,23 @@ "name": "@yaakapp/app", "version": "1.0.0", "dependencies": { - "@codemirror/commands": "6.7.0", - "@codemirror/lang-javascript": "^6.2.2", + "@codemirror/commands": "^6.8.1", + "@codemirror/lang-javascript": "^6.2.4", "@codemirror/lang-json": "^6.0.1", - "@codemirror/lang-markdown": "^6.3.1", - "@codemirror/lang-xml": "^6.0.2", - "@codemirror/language": "^6.6.0", - "@codemirror/search": "^6.2.3", + "@codemirror/lang-markdown": "^6.3.2", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.11.0", + "@codemirror/search": "^6.5.11", "@gilbarbara/deep-equal": "^0.3.1", "@lezer/highlight": "^1.1.3", "@lezer/lr": "^1.3.3", "@replit/codemirror-emacs": "^6.1.0", - "@replit/codemirror-vim": "^6.2.1", + "@replit/codemirror-vim": "^6.3.0", "@replit/codemirror-vscode-keymap": "^6.0.2", "@tailwindcss/container-queries": "^0.1.1", - "@tanstack/react-query": "^5.66.9", - "@tanstack/react-router": "^1.111.3", - "@tanstack/react-virtual": "^3.13.0", + "@tanstack/react-query": "^5.76.1", + "@tanstack/react-router": "^1.120.3", + "@tanstack/react-virtual": "^3.13.8", "@tauri-apps/api": "^2.4.1", "@tauri-apps/plugin-clipboard-manager": "^2.2.2", "@tauri-apps/plugin-dialog": "^2.2.1", @@ -16071,9 +13992,8 @@ "@tauri-apps/plugin-shell": "^2.2.1", "buffer": "^6.0.3", "classnames": "^2.5.1", - "cm6-graphql": "^0.0.9", - "codemirror": "^6.0.1", - "codemirror-json-schema": "^0.6.1", + "cm6-graphql": "^0.2.1", + "codemirror-json-schema": "0.6.1", "date-fns": "^3.6.0", "deep-equal": "^2.2.3", "eventemitter3": "^5.0.1", @@ -16107,8 +14027,6 @@ "devDependencies": { "@lezer/generator": "^1.7.1", "@tailwindcss/nesting": "^0.0.0-insiders.565cd3e", - "@tanstack/react-query-devtools": "^5.62.8", - "@tanstack/router-devtools": "^1.91.3", "@tanstack/router-plugin": "^1.91.1", "@types/node": "^22.5.4", "@types/papaparse": "^5.3.14", @@ -16125,7 +14043,6 @@ "internal-ip": "^8.0.0", "postcss": "^8.4.45", "postcss-nesting": "^13.0.0", - "react-devtools": "^5.3.1", "tailwindcss": "^3.4.10", "vite": "6.2.6", "vite-plugin-static-copy": "^2.2.0", @@ -16559,6 +14476,41 @@ "node": ">=18" } }, + "src-web/node_modules/codemirror-json-schema": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/codemirror-json-schema/-/codemirror-json-schema-0.6.1.tgz", + "integrity": "sha512-QG12Jy917eStZzxurpAE9QUQxF8SS/AYJ9DDteyJZcRGH8ePaBCfQ4KLCNtY6cUKjFeNBgcd5+c6FPAri6pPQg==", + "license": "MIT", + "dependencies": { + "@changesets/changelog-github": "^0.4.8", + "@sagold/json-pointer": "^5.1.1", + "@types/json-schema": "^7.0.12", + "@types/node": "^20.4.2", + "json-schema": "^0.4.0", + "json-schema-library": "^9.1.2" + }, + "optionalDependencies": { + "@codemirror/lang-json": "^6.0.1", + "codemirror-json5": "^1.0.3", + "json5": "^2.2.3" + }, + "peerDependencies": { + "@codemirror/language": "^6.8.0", + "@codemirror/lint": "^6.4.0", + "@codemirror/state": "^6.2.1", + "@codemirror/view": "^6.14.1", + "@lezer/common": "^1.0.3" + } + }, + "src-web/node_modules/codemirror-json-schema/node_modules/@types/node": { + "version": "20.17.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.47.tgz", + "integrity": "sha512-3dLX0Upo1v7RvUimvxLeXqwrfyKxUINk0EAM83swP2mlSUcwV73sZy8XhNz8bcZ3VbsfQyC/y6jRdL5tgCNpDQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, "src-web/node_modules/esbuild": { "version": "0.25.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", @@ -16600,6 +14552,19 @@ "@esbuild/win32-x64": "0.25.2" } }, + "src-web/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "optional": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "src-web/node_modules/nanoid": { "version": "5.0.9", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz", diff --git a/src-web/commands/openSettings.ts b/src-web/commands/openSettings.tsx similarity index 87% rename from src-web/commands/openSettings.ts rename to src-web/commands/openSettings.tsx index 78cc8115e..44ed88fe8 100644 --- a/src-web/commands/openSettings.ts +++ b/src-web/commands/openSettings.tsx @@ -1,4 +1,4 @@ -import { SettingsTab } from '../components/Settings/SettingsTab'; +import type { SettingsTab } from '../components/Settings/Settings'; import { activeWorkspaceIdAtom } from '../hooks/useActiveWorkspace'; import { createFastMutation } from '../hooks/useFastMutation'; import { jotaiStore } from '../lib/jotai'; @@ -14,8 +14,9 @@ export const openSettings = createFastMutation const location = router.buildLocation({ to: '/workspaces/$workspaceId/settings', params: { workspaceId }, - search: { tab: tab ?? SettingsTab.General }, + search: { tab }, }); + await invokeCmd('cmd_new_child_window', { url: location.href, label: 'settings', diff --git a/src-web/components/GraphQLEditor.tsx b/src-web/components/GraphQLEditor.tsx index 681eec001..000c96a2a 100644 --- a/src-web/components/GraphQLEditor.tsx +++ b/src-web/components/GraphQLEditor.tsx @@ -1,6 +1,6 @@ +import type { EditorView } from '@codemirror/view'; import type { HttpRequest } from '@yaakapp-internal/models'; import { updateSchema } from 'cm6-graphql'; -import type { EditorView } from 'codemirror'; import { formatSdl } from 'format-graphql'; import { useEffect, useMemo, useRef } from 'react'; @@ -60,7 +60,7 @@ export function GraphQLEditor({ request, onChange, baseRequest, ...extraEditorPr // Refetch the schema when the URL changes useEffect(() => { - if (editorViewRef.current === null) return; + if (editorViewRef.current == null) return; updateSchema(editorViewRef.current, schema ?? undefined); }, [schema]); diff --git a/src-web/components/GrpcEditor.tsx b/src-web/components/GrpcEditor.tsx index 09e111aa8..13139fa59 100644 --- a/src-web/components/GrpcEditor.tsx +++ b/src-web/components/GrpcEditor.tsx @@ -1,8 +1,8 @@ import { jsonLanguage } from '@codemirror/lang-json'; import { linter } from '@codemirror/lint'; +import type { EditorView } from '@codemirror/view'; import type { GrpcRequest } from '@yaakapp-internal/models'; import classNames from 'classnames'; -import type { EditorView } from 'codemirror'; import { handleRefresh, jsonCompletion, diff --git a/src-web/components/HttpRequestPane.tsx b/src-web/components/HttpRequestPane.tsx index 45ffba497..a4dae84d8 100644 --- a/src-web/components/HttpRequestPane.tsx +++ b/src-web/components/HttpRequestPane.tsx @@ -4,7 +4,7 @@ import type { GenericCompletionOption } from '@yaakapp-internal/plugins'; import classNames from 'classnames'; import { atom, useAtomValue } from 'jotai'; import type { CSSProperties } from 'react'; -import React, { useCallback, useMemo, useState } from 'react'; +import React, { lazy, useCallback, useMemo, useState } from 'react'; import { activeRequestIdAtom } from '../hooks/useActiveRequestId'; import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse'; import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication'; @@ -44,13 +44,18 @@ import { TabContent, Tabs } from './core/Tabs/Tabs'; import { EmptyStateText } from './EmptyStateText'; import { FormMultipartEditor } from './FormMultipartEditor'; import { FormUrlencodedEditor } from './FormUrlencodedEditor'; -import { GraphQLEditor } from './GraphQLEditor'; import { HeadersEditor } from './HeadersEditor'; import { HttpAuthenticationEditor } from './HttpAuthenticationEditor'; -import { MarkdownEditor } from './MarkdownEditor'; import { UrlBar } from './UrlBar'; import { UrlParametersEditor } from './UrlParameterEditor'; +const GraphQLEditor = lazy(() => + import('./GraphQLEditor').then((m) => ({ default: m.GraphQLEditor })), +); +const MarkdownEditor = lazy(() => + import('./MarkdownEditor').then((m) => ({ default: m.MarkdownEditor })), +); + interface Props { style: CSSProperties; fullHeight: boolean; diff --git a/src-web/components/HttpResponsePane.tsx b/src-web/components/HttpResponsePane.tsx index 79ed88b07..65723b409 100644 --- a/src-web/components/HttpResponsePane.tsx +++ b/src-web/components/HttpResponsePane.tsx @@ -1,7 +1,7 @@ import type { HttpResponse } from '@yaakapp-internal/models'; import classNames from 'classnames'; import type { CSSProperties, ReactNode } from 'react'; -import React, { useCallback, useMemo } from 'react'; +import React, { lazy , useCallback, useMemo } from 'react'; import { useLocalStorage } from 'react-use'; import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse'; import { useResponseViewMode } from '../hooks/useResponseViewMode'; @@ -27,7 +27,10 @@ import { CsvViewer } from './responseViewers/CsvViewer'; import { EventStreamViewer } from './responseViewers/EventStreamViewer'; import { HTMLOrTextViewer } from './responseViewers/HTMLOrTextViewer'; import { ImageViewer } from './responseViewers/ImageViewer'; -import { PdfViewer } from './responseViewers/PdfViewer'; + +const PdfViewer = lazy(() => + import('./responseViewers/PdfViewer').then((m) => ({ default: m.PdfViewer })), +); import { SvgViewer } from './responseViewers/SvgViewer'; import { VideoViewer } from './responseViewers/VideoViewer'; import { ErrorBoundary } from './ErrorBoundary'; diff --git a/src-web/components/LicenseBadge.tsx b/src-web/components/LicenseBadge.tsx index fc81b1547..caa37d4f7 100644 --- a/src-web/components/LicenseBadge.tsx +++ b/src-web/components/LicenseBadge.tsx @@ -6,7 +6,6 @@ import { appInfo } from '../hooks/useAppInfo'; import { useLicenseConfirmation } from '../hooks/useLicenseConfirmation'; import { BadgeButton } from './core/BadgeButton'; import type { ButtonProps } from './core/Button'; -import { SettingsTab } from './Settings/SettingsTab'; const details: Record< LicenseCheckStatus['type'], @@ -28,7 +27,7 @@ export function LicenseBadge() { if (check.error) { return ( - openSettings.mutate(SettingsTab.License)}> + openSettings.mutate('license')}> License Error ); @@ -64,7 +63,7 @@ export function LicenseBadge() { hasDismissedTrial: true, })); } - openSettings.mutate(SettingsTab.License); + openSettings.mutate('license'); }} > {detail.label} diff --git a/src-web/components/Settings/Settings.tsx b/src-web/components/Settings/Settings.tsx index 6f0d810ae..9b5208a74 100644 --- a/src-web/components/Settings/Settings.tsx +++ b/src-web/components/Settings/Settings.tsx @@ -13,24 +13,23 @@ import { SettingsGeneral } from './SettingsGeneral'; import { SettingsLicense } from './SettingsLicense'; import { SettingsPlugins } from './SettingsPlugins'; import { SettingsProxy } from './SettingsProxy'; -import { SettingsTab } from './SettingsTab'; interface Props { hide?: () => void; } -const tabs = [ - SettingsTab.General, - SettingsTab.Appearance, - SettingsTab.Proxy, - SettingsTab.Plugins, - SettingsTab.License, -]; +const TAB_GENERAL = 'general'; +const TAB_APPEARANCE = 'appearance'; +const TAB_PROXY = 'proxy'; +const TAB_PLUGINS = 'plugins'; +const TAB_LICENSE = 'license'; +const tabs = [TAB_GENERAL, TAB_APPEARANCE, TAB_PROXY, TAB_PLUGINS, TAB_LICENSE] as const; +export type SettingsTab = (typeof tabs)[number]; export default function Settings({ hide }: Props) { const osInfo = useOsInfo(); const { tab: tabFromQuery } = useSearch({ from: '/workspaces/$workspaceId/settings' }); - const [tab, setTab] = useState(tabFromQuery ?? SettingsTab.General); + const [tab, setTab] = useState(tabFromQuery); // Close settings window on escape // TODO: Could this be put in a better place? Eg. in Rust key listener when creating the window @@ -74,19 +73,19 @@ export default function Settings({ hide }: Props) { onChangeValue={setTab} tabs={tabs.map((value) => ({ value, label: capitalize(value) }))} > - + - + - + - + - + diff --git a/src-web/components/Settings/SettingsTab.ts b/src-web/components/Settings/SettingsTab.ts deleted file mode 100644 index 7725bdf84..000000000 --- a/src-web/components/Settings/SettingsTab.ts +++ /dev/null @@ -1,8 +0,0 @@ - -export enum SettingsTab { - General = 'general', - Proxy = 'proxy', - Appearance = 'appearance', - Plugins = 'plugins', - License = 'license', -} diff --git a/src-web/components/SettingsDropdown.tsx b/src-web/components/SettingsDropdown.tsx index 1ede3162e..38f693c38 100644 --- a/src-web/components/SettingsDropdown.tsx +++ b/src-web/components/SettingsDropdown.tsx @@ -13,7 +13,6 @@ import { Dropdown } from './core/Dropdown'; import { Icon } from './core/Icon'; import { IconButton } from './core/IconButton'; import { KeyboardShortcutsDialog } from './KeyboardShortcutsDialog'; -import { SettingsTab } from './Settings/SettingsTab'; export function SettingsDropdown() { const importData = useImportData(); @@ -64,7 +63,7 @@ export function SettingsDropdown() { color: 'success', hidden: check.data == null || check.data.type === 'commercial_use', leftSlot: , - onSelect: () => openSettings.mutate(SettingsTab.License), + onSelect: () => openSettings.mutate('license'), }, { label: 'Check for Updates', diff --git a/src-web/components/UrlBar.tsx b/src-web/components/UrlBar.tsx index 61bc27eb2..2916cbfdb 100644 --- a/src-web/components/UrlBar.tsx +++ b/src-web/components/UrlBar.tsx @@ -1,6 +1,6 @@ +import type { EditorView } from '@codemirror/view'; import type { HttpRequest } from '@yaakapp-internal/models'; import classNames from 'classnames'; -import type { EditorView } from 'codemirror'; import type { FormEvent, ReactNode } from 'react'; import { memo, useRef, useState } from 'react'; import { useHotKey } from '../hooks/useHotKey'; @@ -8,7 +8,7 @@ import type { IconProps } from './core/Icon'; import { IconButton } from './core/IconButton'; import type { InputProps } from './core/Input'; import { Input } from './core/Input'; -import {HStack} from "./core/Stacks"; +import { HStack } from './core/Stacks'; import { RequestMethodDropdown } from './RequestMethodDropdown'; type Props = Pick & { diff --git a/src-web/components/Workspace.tsx b/src-web/components/Workspace.tsx index 838f483b0..af1762341 100644 --- a/src-web/components/Workspace.tsx +++ b/src-web/components/Workspace.tsx @@ -194,12 +194,18 @@ function WorkspaceBody() { if (activeWorkspace == null) { return ( -
+ The active workspace was not found. Select a workspace from the header menu or report this bug to -
+ ); } diff --git a/src-web/components/core/Editor/Editor.tsx b/src-web/components/core/Editor/Editor.tsx index 86b89812f..d4e938389 100644 --- a/src-web/components/core/Editor/Editor.tsx +++ b/src-web/components/core/Editor/Editor.tsx @@ -2,16 +2,15 @@ import { defaultKeymap, historyField, indentWithTab } from '@codemirror/commands import { foldState, forceParsing } from '@codemirror/language'; import type { EditorStateConfig, Extension } from '@codemirror/state'; import { Compartment, EditorState } from '@codemirror/state'; -import { keymap, placeholder as placeholderExt, tooltips } from '@codemirror/view'; +import { EditorView, keymap, placeholder as placeholderExt, tooltips } from '@codemirror/view'; import { emacs } from '@replit/codemirror-emacs'; -import { vim } from '@replit/codemirror-vim'; + import { vscodeKeymap } from '@replit/codemirror-vscode-keymap'; import type { EditorKeymap, EnvironmentVariable } from '@yaakapp-internal/models'; import { settingsAtom } from '@yaakapp-internal/models'; import type { EditorLanguage, TemplateFunction } from '@yaakapp-internal/plugins'; import { parseTemplate } from '@yaakapp-internal/templates'; import classNames from 'classnames'; -import { EditorView } from 'codemirror'; import { useAtomValue } from 'jotai'; import { md5 } from 'js-md5'; import type { MutableRefObject, ReactNode } from 'react'; @@ -48,6 +47,8 @@ import { import type { GenericCompletionConfig } from './genericCompletion'; import { singleLineExtensions } from './singleLine'; +const { vim } = await import('@replit/codemirror-vim'); + // VSCode's Tab actions mess with the single-line editor tab actions, so remove it. const vsCodeWithoutTab = vscodeKeymap.filter((k) => k.key !== 'Tab'); @@ -365,7 +366,7 @@ export const Editor = forwardRef(function E useEffect(() => { if (cm.current === null) return; const { view, languageCompartment } = cm.current; - const ext = getLanguageExtension({ + getLanguageExtension({ useTemplating, language, environmentVariables, @@ -374,8 +375,9 @@ export const Editor = forwardRef(function E onClickVariable, onClickMissingVariable, onClickPathParameter, + }).then((ext) => { + view.dispatch({ effects: languageCompartment.reconfigure(ext) }); }); - view.dispatch({ effects: languageCompartment.reconfigure(ext) }); }, [ language, autocomplete, @@ -399,7 +401,7 @@ export const Editor = forwardRef(function E try { const languageCompartment = new Compartment(); - const langExt = getLanguageExtension({ + getLanguageExtension({ useTemplating, language, completionOptions, @@ -408,57 +410,57 @@ export const Editor = forwardRef(function E onClickVariable, onClickMissingVariable, onClickPathParameter, + }).then((langExt) => { + const extensions = [ + languageCompartment.of(langExt), + placeholderCompartment.current.of(placeholderExt(placeholderElFromText(placeholder))), + wrapLinesCompartment.current.of(wrapLines ? EditorView.lineWrapping : emptyExtension), + tabIndentCompartment.current.of( + !disableTabIndent ? keymap.of([indentWithTab]) : emptyExtension, + ), + keymapCompartment.current.of( + keymapExtensions[settings.editorKeymap] ?? keymapExtensions['default'], + ), + ...getExtensions({ + container, + readOnly, + singleLine, + hideGutter, + stateKey, + onChange: handleChange, + onPaste: handlePaste, + onPasteOverwrite: handlePasteOverwrite, + onFocus: handleFocus, + onBlur: handleBlur, + onKeyDown: handleKeyDown, + }), + ...(extraExtensions ?? []), + ]; + + const cachedJsonState = getCachedEditorState(defaultValue ?? '', stateKey); + + const doc = `${defaultValue ?? ''}`; + const config: EditorStateConfig = { extensions, doc }; + + const state = cachedJsonState + ? EditorState.fromJSON(cachedJsonState, config, stateFields) + : EditorState.create(config); + + const view = new EditorView({ state, parent: container }); + + // For large documents, the parser may parse the max number of lines and fail to add + // things like fold markers because of it. + // This forces it to parse more but keeps the timeout to the default of 100 ms. + forceParsing(view, 9e6, 100); + + cm.current = { view, languageCompartment }; + if (autoFocus) { + view.focus(); + } + if (autoSelect) { + view.dispatch({ selection: { anchor: 0, head: view.state.doc.length } }); + } }); - - const extensions = [ - languageCompartment.of(langExt), - placeholderCompartment.current.of(placeholderExt(placeholderElFromText(placeholder))), - wrapLinesCompartment.current.of(wrapLines ? EditorView.lineWrapping : emptyExtension), - tabIndentCompartment.current.of( - !disableTabIndent ? keymap.of([indentWithTab]) : emptyExtension, - ), - keymapCompartment.current.of( - keymapExtensions[settings.editorKeymap] ?? keymapExtensions['default'], - ), - ...getExtensions({ - container, - readOnly, - singleLine, - hideGutter, - stateKey, - onChange: handleChange, - onPaste: handlePaste, - onPasteOverwrite: handlePasteOverwrite, - onFocus: handleFocus, - onBlur: handleBlur, - onKeyDown: handleKeyDown, - }), - ...(extraExtensions ?? []), - ]; - - const cachedJsonState = getCachedEditorState(defaultValue ?? '', stateKey); - - const doc = `${defaultValue ?? ''}`; - const config: EditorStateConfig = { extensions, doc }; - - const state = cachedJsonState - ? EditorState.fromJSON(cachedJsonState, config, stateFields) - : EditorState.create(config); - - const view = new EditorView({ state, parent: container }); - - // For large documents, the parser may parse the max number of lines and fail to add - // things like fold markers because of it. - // This forces it to parse more but keeps the timeout to the default of 100 ms. - forceParsing(view, 9e6, 100); - - cm.current = { view, languageCompartment }; - if (autoFocus) { - view.focus(); - } - if (autoSelect) { - view.dispatch({ selection: { anchor: 0, head: view.state.doc.length } }); - } } catch (e) { console.log('Failed to initialize Codemirror', e); } diff --git a/src-web/components/core/Editor/extensions.ts b/src-web/components/core/Editor/extensions.ts index 9ec1473f8..05759545a 100644 --- a/src-web/components/core/Editor/extensions.ts +++ b/src-web/components/core/Editor/extensions.ts @@ -5,10 +5,6 @@ import { completionKeymap, } from '@codemirror/autocomplete'; import { history, historyKeymap } from '@codemirror/commands'; -import { javascript } from '@codemirror/lang-javascript'; -import { json } from '@codemirror/lang-json'; -import { markdown } from '@codemirror/lang-markdown'; -import { xml } from '@codemirror/lang-xml'; import type { LanguageSupport } from '@codemirror/language'; import { codeFolding, @@ -27,6 +23,7 @@ import { crosshairCursor, drawSelection, dropCursor, + EditorView, highlightActiveLineGutter, highlightSpecialChars, keymap, @@ -36,15 +33,11 @@ import { import { tags as t } from '@lezer/highlight'; import type { EnvironmentVariable } from '@yaakapp-internal/models'; import { graphql } from 'cm6-graphql'; -import { EditorView } from 'codemirror'; import { pluralizeCount } from '../../../lib/pluralize'; import type { EditorProps } from './Editor'; -import { pairs } from './pairs/extension'; import { text } from './text/extension'; import type { TwigCompletionOption } from './twig/completion'; -import { twig } from './twig/extension'; import { pathParametersPlugin } from './twig/pathParameters'; -import { url } from './url/extension'; export const syntaxHighlightStyle = HighlightStyle.define([ { @@ -75,21 +68,25 @@ const syntaxTheme = EditorView.theme({}, { dark: true }); const closeBracketsExtensions: Extension = [closeBrackets(), keymap.of([...closeBracketsKeymap])]; -const syntaxExtensions: Record, LanguageSupport | null> = { +const syntaxExtensions: Record< + NonNullable, + null | (() => Promise) +> = { graphql: null, - json: json(), - javascript: javascript(), - html: xml(), // HTML as XML because HTML is oddly slow - xml: xml(), - url: url(), - pairs: pairs(), - text: text(), - markdown: markdown(), + json: () => import('@codemirror/lang-json').then((m) => m.json()), + javascript: () => import('@codemirror/lang-javascript').then((m) => m.javascript()), + // HTML as XML because HTML is oddly slow + html: () => import('@codemirror/lang-xml').then((m) => m.xml()), + xml: () => import('@codemirror/lang-xml').then((m) => m.xml()), + url: () => import('./url/extension').then((m) => m.url()), + pairs: () => import('./pairs/extension').then((m) => m.pairs()), + text: () => import('./text/extension').then((m) => m.text()), + markdown: () => import('@codemirror/lang-markdown').then((m) => m.markdown()), }; const closeBracketsFor: (keyof typeof syntaxExtensions)[] = ['json', 'javascript', 'graphql']; -export function getLanguageExtension({ +export async function getLanguageExtension({ useTemplating, language = 'text', environmentVariables, @@ -122,12 +119,14 @@ export function getLanguageExtension({ return [graphql(), extraExtensions]; } - const base = syntaxExtensions[language ?? 'text'] ?? text(); + const base_ = syntaxExtensions[language ?? 'text'] ?? text(); + const base = typeof base_ === 'function' ? await base_() : text(); if (!useTemplating) { return [base, extraExtensions]; } + const { twig } = await import('./twig/extension'); return twig({ base, environmentVariables, diff --git a/src-web/components/core/Editor/hyperlink/extension.ts b/src-web/components/core/Editor/hyperlink/extension.ts index b2b6bb0ba..0cd8b4986 100644 --- a/src-web/components/core/Editor/hyperlink/extension.ts +++ b/src-web/components/core/Editor/hyperlink/extension.ts @@ -1,6 +1,5 @@ import type { DecorationSet, ViewUpdate } from '@codemirror/view'; -import { Decoration, hoverTooltip, MatchDecorator, ViewPlugin } from '@codemirror/view'; -import { EditorView } from 'codemirror'; +import { Decoration, EditorView, hoverTooltip, MatchDecorator, ViewPlugin } from '@codemirror/view'; const REGEX = /(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+*~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+*.~#?&/={}[\]]*))/g; diff --git a/src-web/components/core/Editor/twig/pathParameters.ts b/src-web/components/core/Editor/twig/pathParameters.ts index 4cd64393e..77f24686b 100644 --- a/src-web/components/core/Editor/twig/pathParameters.ts +++ b/src-web/components/core/Editor/twig/pathParameters.ts @@ -1,8 +1,7 @@ import { syntaxTree } from '@codemirror/language'; import type { Range } from '@codemirror/state'; import type { DecorationSet, ViewUpdate } from '@codemirror/view'; -import { Decoration, ViewPlugin, WidgetType } from '@codemirror/view'; -import { EditorView } from 'codemirror'; +import { Decoration, ViewPlugin, WidgetType, EditorView } from '@codemirror/view'; class PathPlaceholderWidget extends WidgetType { readonly #clickListenerCallback: () => void; diff --git a/src-web/components/core/Editor/twig/templateTags.ts b/src-web/components/core/Editor/twig/templateTags.ts index 9b7650cb9..e34fe5bd0 100644 --- a/src-web/components/core/Editor/twig/templateTags.ts +++ b/src-web/components/core/Editor/twig/templateTags.ts @@ -1,9 +1,8 @@ import { syntaxTree } from '@codemirror/language'; import type { Range } from '@codemirror/state'; import type { DecorationSet, ViewUpdate } from '@codemirror/view'; -import { Decoration, ViewPlugin, WidgetType } from '@codemirror/view'; +import { Decoration, ViewPlugin, WidgetType, EditorView } from '@codemirror/view'; import type { SyntaxNodeRef } from '@lezer/common'; -import { EditorView } from 'codemirror'; import type { TwigCompletionOption } from './completion'; class TemplateTagWidget extends WidgetType { diff --git a/src-web/components/core/Input.tsx b/src-web/components/core/Input.tsx index 6a94fd3f0..5b806eee4 100644 --- a/src-web/components/core/Input.tsx +++ b/src-web/components/core/Input.tsx @@ -1,6 +1,6 @@ +import type { EditorView } from '@codemirror/view'; import type { Color } from '@yaakapp/api'; import classNames from 'classnames'; -import type { EditorView } from 'codemirror'; import type { ReactNode } from 'react'; import { forwardRef, diff --git a/src-web/components/core/PairEditor.tsx b/src-web/components/core/PairEditor.tsx index ff15e2c08..c533bd299 100644 --- a/src-web/components/core/PairEditor.tsx +++ b/src-web/components/core/PairEditor.tsx @@ -1,5 +1,5 @@ +import type { EditorView } from '@codemirror/view'; import classNames from 'classnames'; -import type { EditorView } from 'codemirror'; import { forwardRef, Fragment, diff --git a/src-web/components/responseViewers/PdfViewer.tsx b/src-web/components/responseViewers/PdfViewer.tsx index 0763165ab..5a7e1c37d 100644 --- a/src-web/components/responseViewers/PdfViewer.tsx +++ b/src-web/components/responseViewers/PdfViewer.tsx @@ -7,6 +7,13 @@ import React, { useRef, useState } from 'react'; import { Document, Page } from 'react-pdf'; import { useContainerSize } from '../../hooks/useContainerQuery'; +import('react-pdf').then(({ pdfjs }) => { + pdfjs.GlobalWorkerOptions.workerSrc = new URL( + 'pdfjs-dist/build/pdf.worker.min.mjs', + import.meta.url, + ).toString(); +}); + interface Props { bodyPath: string; } diff --git a/src-web/main.tsx b/src-web/main.tsx index 07f81ed6b..0e31061f5 100644 --- a/src-web/main.tsx +++ b/src-web/main.tsx @@ -9,13 +9,6 @@ import { initSync } from './init/sync'; import { jotaiStore } from './lib/jotai'; import { router } from './lib/router'; -import('react-pdf').then(({ pdfjs }) => { - pdfjs.GlobalWorkerOptions.workerSrc = new URL( - 'pdfjs-dist/build/pdf.worker.min.mjs', - import.meta.url, - ).toString(); -}); - // Hide decorations here because it doesn't work in Rust for some reason (bug?) const osType = type(); if (osType !== 'macos') { diff --git a/src-web/package.json b/src-web/package.json index 378793e11..9db492683 100644 --- a/src-web/package.json +++ b/src-web/package.json @@ -9,23 +9,23 @@ "lint": "tsc --noEmit && eslint . --ext .ts,.tsx" }, "dependencies": { - "@codemirror/commands": "6.7.0", - "@codemirror/lang-javascript": "^6.2.2", + "@codemirror/commands": "^6.8.1", + "@codemirror/lang-javascript": "^6.2.4", "@codemirror/lang-json": "^6.0.1", - "@codemirror/lang-markdown": "^6.3.1", - "@codemirror/lang-xml": "^6.0.2", - "@codemirror/language": "^6.6.0", - "@codemirror/search": "^6.2.3", + "@codemirror/lang-markdown": "^6.3.2", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.11.0", + "@codemirror/search": "^6.5.11", "@gilbarbara/deep-equal": "^0.3.1", "@lezer/highlight": "^1.1.3", "@lezer/lr": "^1.3.3", "@replit/codemirror-emacs": "^6.1.0", - "@replit/codemirror-vim": "^6.2.1", + "@replit/codemirror-vim": "^6.3.0", "@replit/codemirror-vscode-keymap": "^6.0.2", "@tailwindcss/container-queries": "^0.1.1", - "@tanstack/react-query": "^5.66.9", - "@tanstack/react-router": "^1.111.3", - "@tanstack/react-virtual": "^3.13.0", + "@tanstack/react-query": "^5.76.1", + "@tanstack/react-router": "^1.120.3", + "@tanstack/react-virtual": "^3.13.8", "@tauri-apps/api": "^2.4.1", "@tauri-apps/plugin-clipboard-manager": "^2.2.2", "@tauri-apps/plugin-dialog": "^2.2.1", @@ -36,9 +36,8 @@ "@tauri-apps/plugin-shell": "^2.2.1", "buffer": "^6.0.3", "classnames": "^2.5.1", - "cm6-graphql": "^0.0.9", - "codemirror": "^6.0.1", - "codemirror-json-schema": "^0.6.1", + "cm6-graphql": "^0.2.1", + "codemirror-json-schema": "0.6.1", "date-fns": "^3.6.0", "deep-equal": "^2.2.3", "eventemitter3": "^5.0.1", @@ -72,8 +71,6 @@ "devDependencies": { "@lezer/generator": "^1.7.1", "@tailwindcss/nesting": "^0.0.0-insiders.565cd3e", - "@tanstack/react-query-devtools": "^5.62.8", - "@tanstack/router-devtools": "^1.91.3", "@tanstack/router-plugin": "^1.91.1", "@types/node": "^22.5.4", "@types/papaparse": "^5.3.14", @@ -90,7 +87,6 @@ "internal-ip": "^8.0.0", "postcss": "^8.4.45", "postcss-nesting": "^13.0.0", - "react-devtools": "^5.3.1", "tailwindcss": "^3.4.10", "vite": "6.2.6", "vite-plugin-static-copy": "^2.2.0", diff --git a/src-web/routes/__root.tsx b/src-web/routes/__root.tsx index 7bfc978f1..f6b3b060e 100644 --- a/src-web/routes/__root.tsx +++ b/src-web/routes/__root.tsx @@ -15,26 +15,6 @@ import { useOsInfo } from '../hooks/useOsInfo'; import { jotaiStore } from '../lib/jotai'; import { queryClient } from '../lib/queryClient'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars -const TanStackRouterDevtools = - process.env.NODE_ENV === 'production' - ? () => null // Render nothing in production - : React.lazy(() => - import('@tanstack/router-devtools').then((res) => ({ - default: res.TanStackRouterDevtools, - })), - ); - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -const ReactQueryDevtools = - process.env.NODE_ENV === 'production' - ? () => null // Render nothing in production - : React.lazy(() => - import('@tanstack/react-query-devtools').then((res) => ({ - default: res.ReactQueryDevtools, - })), - ); - export const Route = createRootRoute({ component: RouteComponent, errorComponent: RouteError, @@ -66,8 +46,6 @@ function RouteComponent() { - {/**/} - {/**/} ); diff --git a/src-web/routes/workspaces/$workspaceId/settings.tsx b/src-web/routes/workspaces/$workspaceId/settings.tsx index e9b4800e9..95aebe67a 100644 --- a/src-web/routes/workspaces/$workspaceId/settings.tsx +++ b/src-web/routes/workspaces/$workspaceId/settings.tsx @@ -1,18 +1,18 @@ -import { createFileRoute } from '@tanstack/react-router' -import Settings from '../../../components/Settings/Settings' -import { SettingsTab } from '../../../components/Settings/SettingsTab' +import { createFileRoute } from '@tanstack/react-router'; +import type { SettingsTab } from '../../../components/Settings/Settings'; +import Settings from '../../../components/Settings/Settings'; interface SettingsSearchSchema { - tab?: SettingsTab + tab?: SettingsTab; } export const Route = createFileRoute('/workspaces/$workspaceId/settings')({ component: RouteComponent, validateSearch: (search: Record): SettingsSearchSchema => ({ - tab: (search.tab ?? SettingsTab.General) as SettingsTab, + tab: (search.tab ?? 'general') as SettingsTab, }), -}) +}); function RouteComponent() { - return + return ; } diff --git a/src-web/vite.config.ts b/src-web/vite.config.ts index e0edd529b..50c2aa007 100644 --- a/src-web/vite.config.ts +++ b/src-web/vite.config.ts @@ -1,12 +1,12 @@ // @ts-ignore -import {TanStackRouterVite} from '@tanstack/router-plugin/vite'; +import { TanStackRouterVite } from '@tanstack/router-plugin/vite'; import react from '@vitejs/plugin-react'; import reactRefresh from 'eslint-plugin-react-refresh'; -import {internalIpV4} from 'internal-ip'; -import {createRequire} from 'node:module'; +import { internalIpV4 } from 'internal-ip'; +import { createRequire } from 'node:module'; import path from 'node:path'; -import {defineConfig, normalizePath} from 'vite'; -import {viteStaticCopy} from 'vite-plugin-static-copy'; +import { defineConfig, normalizePath } from 'vite'; +import { viteStaticCopy } from 'vite-plugin-static-copy'; import svgr from 'vite-plugin-svgr'; import topLevelAwait from 'vite-plugin-top-level-await'; import wasm from 'vite-plugin-wasm'; From b52bf7cd564881b40a91640c9140a1d24b5e3862 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 15 May 2025 09:37:05 -0700 Subject: [PATCH 179/996] Fix HttpResponse AnyModel deserialization --- src-tauri/yaak-models/src/models.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index 607734d28..0a3f18204 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -1997,6 +1997,7 @@ impl<'de> Deserialize<'de> for AnyModel { Some(m) if m == "grpc_event" => AnyModel::GrpcEvent(fv(value).unwrap()), Some(m) if m == "grpc_request" => AnyModel::GrpcRequest(fv(value).unwrap()), Some(m) if m == "http_request" => AnyModel::HttpRequest(fv(value).unwrap()), + Some(m) if m == "http_response" => AnyModel::HttpResponse(fv(value).unwrap()), Some(m) if m == "key_value" => AnyModel::KeyValue(fv(value).unwrap()), Some(m) if m == "plugin" => AnyModel::Plugin(fv(value).unwrap()), Some(m) if m == "settings" => AnyModel::Settings(fv(value).unwrap()), From 3184c1b79e13db80046cf20508da4fa597102124 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 15 May 2025 12:29:45 -0700 Subject: [PATCH 180/996] Remove dynamic imports --- src-web/components/HttpRequestPane.tsx | 11 +- src-web/components/HttpResponsePane.tsx | 7 +- .../components/RedirectToLatestWorkspace.tsx | 1 + src-web/components/core/Editor/Editor.tsx | 109 +++++++++--------- src-web/components/core/Editor/extensions.ts | 30 +++-- 5 files changed, 77 insertions(+), 81 deletions(-) diff --git a/src-web/components/HttpRequestPane.tsx b/src-web/components/HttpRequestPane.tsx index a4dae84d8..3506434c4 100644 --- a/src-web/components/HttpRequestPane.tsx +++ b/src-web/components/HttpRequestPane.tsx @@ -4,7 +4,7 @@ import type { GenericCompletionOption } from '@yaakapp-internal/plugins'; import classNames from 'classnames'; import { atom, useAtomValue } from 'jotai'; import type { CSSProperties } from 'react'; -import React, { lazy, useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { activeRequestIdAtom } from '../hooks/useActiveRequestId'; import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse'; import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication'; @@ -46,15 +46,10 @@ import { FormMultipartEditor } from './FormMultipartEditor'; import { FormUrlencodedEditor } from './FormUrlencodedEditor'; import { HeadersEditor } from './HeadersEditor'; import { HttpAuthenticationEditor } from './HttpAuthenticationEditor'; +import { MarkdownEditor } from './MarkdownEditor'; import { UrlBar } from './UrlBar'; import { UrlParametersEditor } from './UrlParameterEditor'; - -const GraphQLEditor = lazy(() => - import('./GraphQLEditor').then((m) => ({ default: m.GraphQLEditor })), -); -const MarkdownEditor = lazy(() => - import('./MarkdownEditor').then((m) => ({ default: m.MarkdownEditor })), -); +import { GraphQLEditor } from './GraphQLEditor'; interface Props { style: CSSProperties; diff --git a/src-web/components/HttpResponsePane.tsx b/src-web/components/HttpResponsePane.tsx index 65723b409..79ed88b07 100644 --- a/src-web/components/HttpResponsePane.tsx +++ b/src-web/components/HttpResponsePane.tsx @@ -1,7 +1,7 @@ import type { HttpResponse } from '@yaakapp-internal/models'; import classNames from 'classnames'; import type { CSSProperties, ReactNode } from 'react'; -import React, { lazy , useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { useLocalStorage } from 'react-use'; import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse'; import { useResponseViewMode } from '../hooks/useResponseViewMode'; @@ -27,10 +27,7 @@ import { CsvViewer } from './responseViewers/CsvViewer'; import { EventStreamViewer } from './responseViewers/EventStreamViewer'; import { HTMLOrTextViewer } from './responseViewers/HTMLOrTextViewer'; import { ImageViewer } from './responseViewers/ImageViewer'; - -const PdfViewer = lazy(() => - import('./responseViewers/PdfViewer').then((m) => ({ default: m.PdfViewer })), -); +import { PdfViewer } from './responseViewers/PdfViewer'; import { SvgViewer } from './responseViewers/SvgViewer'; import { VideoViewer } from './responseViewers/VideoViewer'; import { ErrorBoundary } from './ErrorBoundary'; diff --git a/src-web/components/RedirectToLatestWorkspace.tsx b/src-web/components/RedirectToLatestWorkspace.tsx index 958ae55d4..acc87588d 100644 --- a/src-web/components/RedirectToLatestWorkspace.tsx +++ b/src-web/components/RedirectToLatestWorkspace.tsx @@ -32,6 +32,7 @@ export function RedirectToLatestWorkspace() { request_id: requestId, }; + console.log("Redirecting to workspace", params, search); await router.navigate({ to: '/workspaces/$workspaceId', params, search }); })(); }, [recentWorkspaces, workspaces, workspaces.length]); diff --git a/src-web/components/core/Editor/Editor.tsx b/src-web/components/core/Editor/Editor.tsx index d4e938389..285a0f1c0 100644 --- a/src-web/components/core/Editor/Editor.tsx +++ b/src-web/components/core/Editor/Editor.tsx @@ -4,6 +4,7 @@ import type { EditorStateConfig, Extension } from '@codemirror/state'; import { Compartment, EditorState } from '@codemirror/state'; import { EditorView, keymap, placeholder as placeholderExt, tooltips } from '@codemirror/view'; import { emacs } from '@replit/codemirror-emacs'; +import { vim } from '@replit/codemirror-vim'; import { vscodeKeymap } from '@replit/codemirror-vscode-keymap'; import type { EditorKeymap, EnvironmentVariable } from '@yaakapp-internal/models'; @@ -47,8 +48,6 @@ import { import type { GenericCompletionConfig } from './genericCompletion'; import { singleLineExtensions } from './singleLine'; -const { vim } = await import('@replit/codemirror-vim'); - // VSCode's Tab actions mess with the single-line editor tab actions, so remove it. const vsCodeWithoutTab = vscodeKeymap.filter((k) => k.key !== 'Tab'); @@ -366,7 +365,7 @@ export const Editor = forwardRef(function E useEffect(() => { if (cm.current === null) return; const { view, languageCompartment } = cm.current; - getLanguageExtension({ + const ext = getLanguageExtension({ useTemplating, language, environmentVariables, @@ -375,9 +374,8 @@ export const Editor = forwardRef(function E onClickVariable, onClickMissingVariable, onClickPathParameter, - }).then((ext) => { - view.dispatch({ effects: languageCompartment.reconfigure(ext) }); }); + view.dispatch({ effects: languageCompartment.reconfigure(ext) }); }, [ language, autocomplete, @@ -401,7 +399,7 @@ export const Editor = forwardRef(function E try { const languageCompartment = new Compartment(); - getLanguageExtension({ + const langExt = getLanguageExtension({ useTemplating, language, completionOptions, @@ -410,57 +408,56 @@ export const Editor = forwardRef(function E onClickVariable, onClickMissingVariable, onClickPathParameter, - }).then((langExt) => { - const extensions = [ - languageCompartment.of(langExt), - placeholderCompartment.current.of(placeholderExt(placeholderElFromText(placeholder))), - wrapLinesCompartment.current.of(wrapLines ? EditorView.lineWrapping : emptyExtension), - tabIndentCompartment.current.of( - !disableTabIndent ? keymap.of([indentWithTab]) : emptyExtension, - ), - keymapCompartment.current.of( - keymapExtensions[settings.editorKeymap] ?? keymapExtensions['default'], - ), - ...getExtensions({ - container, - readOnly, - singleLine, - hideGutter, - stateKey, - onChange: handleChange, - onPaste: handlePaste, - onPasteOverwrite: handlePasteOverwrite, - onFocus: handleFocus, - onBlur: handleBlur, - onKeyDown: handleKeyDown, - }), - ...(extraExtensions ?? []), - ]; - - const cachedJsonState = getCachedEditorState(defaultValue ?? '', stateKey); - - const doc = `${defaultValue ?? ''}`; - const config: EditorStateConfig = { extensions, doc }; - - const state = cachedJsonState - ? EditorState.fromJSON(cachedJsonState, config, stateFields) - : EditorState.create(config); - - const view = new EditorView({ state, parent: container }); - - // For large documents, the parser may parse the max number of lines and fail to add - // things like fold markers because of it. - // This forces it to parse more but keeps the timeout to the default of 100 ms. - forceParsing(view, 9e6, 100); - - cm.current = { view, languageCompartment }; - if (autoFocus) { - view.focus(); - } - if (autoSelect) { - view.dispatch({ selection: { anchor: 0, head: view.state.doc.length } }); - } }); + const extensions = [ + languageCompartment.of(langExt), + placeholderCompartment.current.of(placeholderExt(placeholderElFromText(placeholder))), + wrapLinesCompartment.current.of(wrapLines ? EditorView.lineWrapping : emptyExtension), + tabIndentCompartment.current.of( + !disableTabIndent ? keymap.of([indentWithTab]) : emptyExtension, + ), + keymapCompartment.current.of( + keymapExtensions[settings.editorKeymap] ?? keymapExtensions['default'], + ), + ...getExtensions({ + container, + readOnly, + singleLine, + hideGutter, + stateKey, + onChange: handleChange, + onPaste: handlePaste, + onPasteOverwrite: handlePasteOverwrite, + onFocus: handleFocus, + onBlur: handleBlur, + onKeyDown: handleKeyDown, + }), + ...(extraExtensions ?? []), + ]; + + const cachedJsonState = getCachedEditorState(defaultValue ?? '', stateKey); + + const doc = `${defaultValue ?? ''}`; + const config: EditorStateConfig = { extensions, doc }; + + const state = cachedJsonState + ? EditorState.fromJSON(cachedJsonState, config, stateFields) + : EditorState.create(config); + + const view = new EditorView({ state, parent: container }); + + // For large documents, the parser may parse the max number of lines and fail to add + // things like fold markers because of it. + // This forces it to parse more but keeps the timeout to the default of 100 ms. + forceParsing(view, 9e6, 100); + + cm.current = { view, languageCompartment }; + if (autoFocus) { + view.focus(); + } + if (autoSelect) { + view.dispatch({ selection: { anchor: 0, head: view.state.doc.length } }); + } } catch (e) { console.log('Failed to initialize Codemirror', e); } diff --git a/src-web/components/core/Editor/extensions.ts b/src-web/components/core/Editor/extensions.ts index 05759545a..02ff07c62 100644 --- a/src-web/components/core/Editor/extensions.ts +++ b/src-web/components/core/Editor/extensions.ts @@ -5,6 +5,8 @@ import { completionKeymap, } from '@codemirror/autocomplete'; import { history, historyKeymap } from '@codemirror/commands'; +import { javascript } from '@codemirror/lang-javascript'; +import { markdown } from '@codemirror/lang-markdown'; import type { LanguageSupport } from '@codemirror/language'; import { codeFolding, @@ -37,7 +39,12 @@ import { pluralizeCount } from '../../../lib/pluralize'; import type { EditorProps } from './Editor'; import { text } from './text/extension'; import type { TwigCompletionOption } from './twig/completion'; +import { twig } from './twig/extension'; import { pathParametersPlugin } from './twig/pathParameters'; +import { json } from '@codemirror/lang-json'; +import { xml } from '@codemirror/lang-xml'; +import { pairs } from './pairs/extension'; +import { url } from './url/extension'; export const syntaxHighlightStyle = HighlightStyle.define([ { @@ -70,23 +77,23 @@ const closeBracketsExtensions: Extension = [closeBrackets(), keymap.of([...close const syntaxExtensions: Record< NonNullable, - null | (() => Promise) + null | (() => LanguageSupport) > = { graphql: null, - json: () => import('@codemirror/lang-json').then((m) => m.json()), - javascript: () => import('@codemirror/lang-javascript').then((m) => m.javascript()), + json: json, + javascript: javascript, // HTML as XML because HTML is oddly slow - html: () => import('@codemirror/lang-xml').then((m) => m.xml()), - xml: () => import('@codemirror/lang-xml').then((m) => m.xml()), - url: () => import('./url/extension').then((m) => m.url()), - pairs: () => import('./pairs/extension').then((m) => m.pairs()), - text: () => import('./text/extension').then((m) => m.text()), - markdown: () => import('@codemirror/lang-markdown').then((m) => m.markdown()), + html: xml, + xml: xml, + url: url, + pairs: pairs, + text: text, + markdown: markdown, }; const closeBracketsFor: (keyof typeof syntaxExtensions)[] = ['json', 'javascript', 'graphql']; -export async function getLanguageExtension({ +export function getLanguageExtension({ useTemplating, language = 'text', environmentVariables, @@ -120,13 +127,12 @@ export async function getLanguageExtension({ } const base_ = syntaxExtensions[language ?? 'text'] ?? text(); - const base = typeof base_ === 'function' ? await base_() : text(); + const base = typeof base_ === 'function' ? base_() : text(); if (!useTemplating) { return [base, extraExtensions]; } - const { twig } = await import('./twig/extension'); return twig({ base, environmentVariables, From 749df338c55cd4802e29b18d3f32b4be683b6427 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 15 May 2025 14:29:29 -0700 Subject: [PATCH 181/996] Disable wasm-opt --- src-tauri/yaak-templates/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src-tauri/yaak-templates/Cargo.toml b/src-tauri/yaak-templates/Cargo.toml index 2357fb426..be9061aa2 100644 --- a/src-tauri/yaak-templates/Cargo.toml +++ b/src-tauri/yaak-templates/Cargo.toml @@ -4,6 +4,9 @@ version = "0.1.0" edition = "2024" publish = false +[package.metadata.wasm-pack.profile.release] +wasm-opt = false # Causes errors in CI (haven't figured out why yet) + [lib] crate-type = ["cdylib", "rlib"] From 9615d3e29bb2118d02758301653d0e921b7850df Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 16 May 2025 07:17:22 -0700 Subject: [PATCH 182/996] Add audience parameter to OAuth 2 Closes https://feedback.yaak.app/p/how-do-i-send-an-audience-using-oauth2 --- plugins/auth-oauth2/src/getAccessToken.ts | 3 +++ plugins/auth-oauth2/src/grants/authorizationCode.ts | 4 ++++ plugins/auth-oauth2/src/grants/clientCredentials.ts | 3 +++ plugins/auth-oauth2/src/grants/implicit.ts | 3 +++ plugins/auth-oauth2/src/grants/password.ts | 3 +++ plugins/auth-oauth2/src/index.ts | 10 ++++++++++ 6 files changed, 26 insertions(+) diff --git a/plugins/auth-oauth2/src/getAccessToken.ts b/plugins/auth-oauth2/src/getAccessToken.ts index 6d04a379d..0304916ff 100644 --- a/plugins/auth-oauth2/src/getAccessToken.ts +++ b/plugins/auth-oauth2/src/getAccessToken.ts @@ -6,6 +6,7 @@ export async function getAccessToken( ctx: Context, { accessTokenUrl, scope, + audience, params, grantType, credentialsInBody, @@ -17,6 +18,7 @@ export async function getAccessToken( grantType: string; accessTokenUrl: string; scope: string | null; + audience: string | null; credentialsInBody: boolean; params: HttpUrlParameter[]; }): Promise { @@ -39,6 +41,7 @@ export async function getAccessToken( }; if (scope) httpRequest.body!.form.push({ name: 'scope', value: scope }); + if (scope) httpRequest.body!.form.push({ name: 'audience', value: audience }); if (credentialsInBody) { httpRequest.body!.form.push({ name: 'client_id', value: clientId }); diff --git a/plugins/auth-oauth2/src/grants/authorizationCode.ts b/plugins/auth-oauth2/src/grants/authorizationCode.ts index 247a3a725..c9400d6be 100644 --- a/plugins/auth-oauth2/src/grants/authorizationCode.ts +++ b/plugins/auth-oauth2/src/grants/authorizationCode.ts @@ -19,6 +19,7 @@ export async function getAuthorizationCode( redirectUri, scope, state, + audience, credentialsInBody, pkce, }: { @@ -29,6 +30,7 @@ export async function getAuthorizationCode( redirectUri: string | null; scope: string | null; state: string | null; + audience: string | null; credentialsInBody: boolean; pkce: { challengeMethod: string | null; @@ -53,6 +55,7 @@ export async function getAuthorizationCode( if (redirectUri) authorizationUrl.searchParams.set('redirect_uri', redirectUri); if (scope) authorizationUrl.searchParams.set('scope', scope); if (state) authorizationUrl.searchParams.set('state', state); + if (audience) authorizationUrl.searchParams.set('audience', audience); if (pkce) { const verifier = pkce.codeVerifier || createPkceCodeVerifier(); const challengeMethod = pkce.challengeMethod || DEFAULT_PKCE_METHOD; @@ -95,6 +98,7 @@ export async function getAuthorizationCode( clientId, clientSecret, scope, + audience, credentialsInBody, params: [ { name: 'code', value: code }, diff --git a/plugins/auth-oauth2/src/grants/clientCredentials.ts b/plugins/auth-oauth2/src/grants/clientCredentials.ts index 6fb8e6e4c..9543d9b7e 100644 --- a/plugins/auth-oauth2/src/grants/clientCredentials.ts +++ b/plugins/auth-oauth2/src/grants/clientCredentials.ts @@ -10,12 +10,14 @@ export async function getClientCredentials( clientId, clientSecret, scope, + audience, credentialsInBody, }: { accessTokenUrl: string; clientId: string; clientSecret: string; scope: string | null; + audience: string | null; credentialsInBody: boolean; }, ) { @@ -29,6 +31,7 @@ export async function getClientCredentials( const response = await getAccessToken(ctx, { grantType: 'client_credentials', accessTokenUrl, + audience, clientId, clientSecret, scope, diff --git a/plugins/auth-oauth2/src/grants/implicit.ts b/plugins/auth-oauth2/src/grants/implicit.ts index 15105b0f6..a54d1964e 100644 --- a/plugins/auth-oauth2/src/grants/implicit.ts +++ b/plugins/auth-oauth2/src/grants/implicit.ts @@ -11,6 +11,7 @@ export function getImplicit( redirectUri, scope, state, + audience, }: { authorizationUrl: string; responseType: string; @@ -18,6 +19,7 @@ export function getImplicit( redirectUri: string | null; scope: string | null; state: string | null; + audience: string | null; }, ) :Promise { return new Promise(async (resolve, reject) => { @@ -34,6 +36,7 @@ export function getImplicit( if (redirectUri) authorizationUrl.searchParams.set('redirect_uri', redirectUri); if (scope) authorizationUrl.searchParams.set('scope', scope); if (state) authorizationUrl.searchParams.set('state', state); + if (audience) authorizationUrl.searchParams.set('audience', audience); if (responseType.includes('id_token')) { authorizationUrl.searchParams.set('nonce', String(Math.floor(Math.random() * 9999999999999) + 1)); } diff --git a/plugins/auth-oauth2/src/grants/password.ts b/plugins/auth-oauth2/src/grants/password.ts index f1a685da7..2192345fd 100644 --- a/plugins/auth-oauth2/src/grants/password.ts +++ b/plugins/auth-oauth2/src/grants/password.ts @@ -13,6 +13,7 @@ export async function getPassword( username, password, credentialsInBody, + audience, scope, }: { accessTokenUrl: string; @@ -21,6 +22,7 @@ export async function getPassword( username: string; password: string; scope: string | null; + audience: string | null; credentialsInBody: boolean; }, ): Promise { @@ -40,6 +42,7 @@ export async function getPassword( clientId, clientSecret, scope, + audience, grantType: 'password', credentialsInBody, params: [ diff --git a/plugins/auth-oauth2/src/index.ts b/plugins/auth-oauth2/src/index.ts index 60ae2cf3e..731bf2913 100644 --- a/plugins/auth-oauth2/src/index.ts +++ b/plugins/auth-oauth2/src/index.ts @@ -156,6 +156,12 @@ export const plugin: PluginDefinition = { optional: true, dynamic: hiddenIfNot(['authorization_code', 'implicit']), }, + { + type: 'text', + name: 'audience', + label: 'Audience', + optional: true, + }, { type: 'checkbox', name: 'usePkce', @@ -258,6 +264,7 @@ export const plugin: PluginDefinition = { clientSecret: stringArg(values, 'clientSecret'), redirectUri: stringArgOrNull(values, 'redirectUri'), scope: stringArgOrNull(values, 'scope'), + audience: stringArgOrNull(values, 'audience'), state: stringArgOrNull(values, 'state'), credentialsInBody, pkce: values.usePkce ? { @@ -273,6 +280,7 @@ export const plugin: PluginDefinition = { redirectUri: stringArgOrNull(values, 'redirectUri'), responseType: stringArg(values, 'responseType'), scope: stringArgOrNull(values, 'scope'), + audience: stringArgOrNull(values, 'audience'), state: stringArgOrNull(values, 'state'), }); } else if (grantType === 'client_credentials') { @@ -282,6 +290,7 @@ export const plugin: PluginDefinition = { clientId: stringArg(values, 'clientId'), clientSecret: stringArg(values, 'clientSecret'), scope: stringArgOrNull(values, 'scope'), + audience: stringArgOrNull(values, 'audience'), credentialsInBody, }); } else if (grantType === 'password') { @@ -293,6 +302,7 @@ export const plugin: PluginDefinition = { username: stringArg(values, 'username'), password: stringArg(values, 'password'), scope: stringArgOrNull(values, 'scope'), + audience: stringArgOrNull(values, 'audience'), credentialsInBody, }); } else { From 0be7d0283b878f446b1a5ed9dd1b9b3c39b05473 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 16 May 2025 07:53:22 -0700 Subject: [PATCH 183/996] Add ref= to external links pointing to yaak.app --- src-tauri/capabilities/capabilities.json | 1 + src-web/components/IsDev.tsx | 3 +-- src-web/components/LicenseBadge.tsx | 2 +- src-web/components/Settings/SettingsGeneral.tsx | 3 +-- src-web/components/SettingsDropdown.tsx | 3 +-- src-web/components/core/Link.tsx | 9 ++++++++- src-web/hooks/useAppInfo.ts | 15 --------------- src-web/hooks/useCheckForUpdates.tsx | 4 +--- src-web/hooks/useSyncWorkspaceRequestTitle.ts | 2 +- src-web/lib/appInfo.ts | 16 ++++++++++++++++ 10 files changed, 31 insertions(+), 27 deletions(-) delete mode 100644 src-web/hooks/useAppInfo.ts create mode 100644 src-web/lib/appInfo.ts diff --git a/src-tauri/capabilities/capabilities.json b/src-tauri/capabilities/capabilities.json index a1c625c21..456d75d65 100644 --- a/src-tauri/capabilities/capabilities.json +++ b/src-tauri/capabilities/capabilities.json @@ -7,6 +7,7 @@ "*" ], "permissions": [ + "core:app:allow-identifier", "core:event:allow-emit", "core:event:allow-listen", "core:event:allow-unlisten", diff --git a/src-web/components/IsDev.tsx b/src-web/components/IsDev.tsx index 3c3806884..d850c5e34 100644 --- a/src-web/components/IsDev.tsx +++ b/src-web/components/IsDev.tsx @@ -1,12 +1,11 @@ import type { ReactNode } from 'react'; -import { useAppInfo } from '../hooks/useAppInfo'; +import { appInfo } from '../lib/appInfo'; interface Props { children: ReactNode; } export function IsDev({ children }: Props) { - const appInfo = useAppInfo(); if (!appInfo.isDev) { return null; } diff --git a/src-web/components/LicenseBadge.tsx b/src-web/components/LicenseBadge.tsx index caa37d4f7..5868cb5cd 100644 --- a/src-web/components/LicenseBadge.tsx +++ b/src-web/components/LicenseBadge.tsx @@ -2,7 +2,7 @@ import type { LicenseCheckStatus } from '@yaakapp-internal/license'; import { useLicense } from '@yaakapp-internal/license'; import type { ReactNode } from 'react'; import { openSettings } from '../commands/openSettings'; -import { appInfo } from '../hooks/useAppInfo'; +import { appInfo } from '../lib/appInfo'; import { useLicenseConfirmation } from '../hooks/useLicenseConfirmation'; import { BadgeButton } from './core/BadgeButton'; import type { ButtonProps } from './core/Button'; diff --git a/src-web/components/Settings/SettingsGeneral.tsx b/src-web/components/Settings/SettingsGeneral.tsx index ec6b0ebe3..a58f8d267 100644 --- a/src-web/components/Settings/SettingsGeneral.tsx +++ b/src-web/components/Settings/SettingsGeneral.tsx @@ -3,7 +3,7 @@ import { patchModel, settingsAtom } from '@yaakapp-internal/models'; import { useAtomValue } from 'jotai'; import React from 'react'; import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace'; -import { useAppInfo } from '../../hooks/useAppInfo'; +import { appInfo } from '../../lib/appInfo'; import { useCheckForUpdates } from '../../hooks/useCheckForUpdates'; import { revealInFinderText } from '../../lib/reveal'; import { Checkbox } from '../core/Checkbox'; @@ -18,7 +18,6 @@ import { VStack } from '../core/Stacks'; export function SettingsGeneral() { const workspace = useAtomValue(activeWorkspaceAtom); const settings = useAtomValue(settingsAtom); - const appInfo = useAppInfo(); const checkForUpdates = useCheckForUpdates(); if (settings == null || workspace == null) { diff --git a/src-web/components/SettingsDropdown.tsx b/src-web/components/SettingsDropdown.tsx index 38f693c38..6710cebc7 100644 --- a/src-web/components/SettingsDropdown.tsx +++ b/src-web/components/SettingsDropdown.tsx @@ -2,7 +2,7 @@ import { openUrl } from '@tauri-apps/plugin-opener'; import { useLicense } from '@yaakapp-internal/license'; import { useRef } from 'react'; import { openSettings } from '../commands/openSettings'; -import { useAppInfo } from '../hooks/useAppInfo'; +import { appInfo } from '../lib/appInfo'; import { useCheckForUpdates } from '../hooks/useCheckForUpdates'; import { useExportData } from '../hooks/useExportData'; import { useImportData } from '../hooks/useImportData'; @@ -17,7 +17,6 @@ import { KeyboardShortcutsDialog } from './KeyboardShortcutsDialog'; export function SettingsDropdown() { const importData = useImportData(); const exportData = useExportData(); - const appInfo = useAppInfo(); const dropdownRef = useRef(null); const checkForUpdates = useCheckForUpdates(); const { check } = useLicense(); diff --git a/src-web/components/core/Link.tsx b/src-web/components/core/Link.tsx index 2e0988ced..7dbd3d1ed 100644 --- a/src-web/components/core/Link.tsx +++ b/src-web/components/core/Link.tsx @@ -1,6 +1,7 @@ import { Link as RouterLink } from '@tanstack/react-router'; import classNames from 'classnames'; import type { HTMLAttributes } from 'react'; +import { appInfo } from '../../lib/appInfo'; import { Icon } from './Icon'; interface Props extends HTMLAttributes { @@ -13,9 +14,15 @@ export function Link({ href, children, className, ...other }: Props) { className = classNames(className, 'relative underline hover:text-violet-600'); if (isExternal) { + let finalHref = href; + if (href.startsWith('https://yaak.app')) { + const url = new URL(href); + url.searchParams.set('ref', appInfo.identifier); + finalHref = url.toString(); + } return ( { diff --git a/src-web/hooks/useSyncWorkspaceRequestTitle.ts b/src-web/hooks/useSyncWorkspaceRequestTitle.ts index 50af0265e..5a4a31131 100644 --- a/src-web/hooks/useSyncWorkspaceRequestTitle.ts +++ b/src-web/hooks/useSyncWorkspaceRequestTitle.ts @@ -1,11 +1,11 @@ import { setWindowTitle } from '@yaakapp-internal/mac-window'; import { useAtomValue } from 'jotai'; import { useEffect } from 'react'; +import { appInfo } from '../lib/appInfo'; import { resolvedModelName } from '../lib/resolvedModelName'; import { useActiveEnvironment } from './useActiveEnvironment'; import { activeRequestAtom } from './useActiveRequest'; import { activeWorkspaceAtom } from './useActiveWorkspace'; -import { appInfo } from './useAppInfo'; export function useSyncWorkspaceRequestTitle() { const activeWorkspace = useAtomValue(activeWorkspaceAtom); diff --git a/src-web/lib/appInfo.ts b/src-web/lib/appInfo.ts new file mode 100644 index 000000000..4f4e5264c --- /dev/null +++ b/src-web/lib/appInfo.ts @@ -0,0 +1,16 @@ +import { getIdentifier } from '@tauri-apps/api/app'; +import { invokeCmd } from './tauri'; + +export interface AppInfo { + isDev: boolean; + version: string; + name: string; + appDataDir: string; + appLogDir: string; + identifier: string; +} + +export const appInfo = { + ...(await invokeCmd('cmd_metadata')), + identifier: await getIdentifier(), +} as AppInfo; From c73f0b02bd1fd9dae2aed2db965cf4c608953281 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 16 May 2025 08:16:18 -0700 Subject: [PATCH 184/996] print body in OAuth 2 http errors --- plugins/auth-oauth2/src/getAccessToken.ts | 6 +++--- plugins/auth-oauth2/src/getOrRefreshAccessToken.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/auth-oauth2/src/getAccessToken.ts b/plugins/auth-oauth2/src/getAccessToken.ts index 0304916ff..1129508a5 100644 --- a/plugins/auth-oauth2/src/getAccessToken.ts +++ b/plugins/auth-oauth2/src/getAccessToken.ts @@ -53,12 +53,12 @@ export async function getAccessToken( const resp = await ctx.httpRequest.send({ httpRequest }); + const body = resp.bodyPath ? readFileSync(resp.bodyPath, 'utf8') : ''; + if (resp.status < 200 || resp.status >= 300) { - throw new Error('Failed to fetch access token with status=' + resp.status); + throw new Error('Failed to fetch access token with status=' + resp.status + ' and body=' + body); } - const body = readFileSync(resp.bodyPath ?? '', 'utf8'); - let response; try { response = JSON.parse(body); diff --git a/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts b/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts index 02ff377fa..43df1402e 100644 --- a/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts +++ b/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts @@ -73,12 +73,12 @@ export async function getOrRefreshAccessToken(ctx: Context, contextId: string, { return null; } + const body = resp.bodyPath ? readFileSync(resp.bodyPath, 'utf8') : ''; + if (resp.status < 200 || resp.status >= 300) { - throw new Error('Failed to fetch access token with status=' + resp.status); + throw new Error('Failed to refresh access token with status=' + resp.status + ' and body=' + body); } - const body = readFileSync(resp.bodyPath ?? '', 'utf8'); - let response; try { response = JSON.parse(body); From 73c366dc27514b01092e2ebd09fe6bb7e91ac7b1 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 16 May 2025 09:12:36 -0700 Subject: [PATCH 185/996] Hopefully fix weird env routing issue --- src-web/commands/createEnvironment.ts | 51 ++++++++++++++++++++ src-web/components/CommandPaletteDialog.tsx | 6 +-- src-web/components/EnvironmentEditDialog.tsx | 45 +++++++++-------- src-web/hooks/useCreateEnvironment.ts | 50 ------------------- 4 files changed, 77 insertions(+), 75 deletions(-) create mode 100644 src-web/commands/createEnvironment.ts delete mode 100644 src-web/hooks/useCreateEnvironment.ts diff --git a/src-web/commands/createEnvironment.ts b/src-web/commands/createEnvironment.ts new file mode 100644 index 000000000..9a12a5d06 --- /dev/null +++ b/src-web/commands/createEnvironment.ts @@ -0,0 +1,51 @@ +import { createWorkspaceModel, type Environment } from '@yaakapp-internal/models'; +import { activeWorkspaceIdAtom } from '../hooks/useActiveWorkspace'; +import { createFastMutation } from '../hooks/useFastMutation'; +import { jotaiStore } from '../lib/jotai'; +import { showPrompt } from '../lib/prompt'; +import { setWorkspaceSearchParams } from '../lib/setWorkspaceSearchParams'; + +export const createEnvironmentAndActivate = createFastMutation< + string | null, + unknown, + Environment | null +>({ + mutationKey: ['create_environment'], + mutationFn: async (baseEnvironment) => { + if (baseEnvironment == null) { + throw new Error('No base environment passed'); + } + + const workspaceId = jotaiStore.get(activeWorkspaceIdAtom); + if (workspaceId == null) { + throw new Error('Cannot create environment when no active workspace'); + } + + const name = await showPrompt({ + id: 'new-environment', + title: 'New Environment', + description: 'Create multiple environments with different sets of variables', + label: 'Name', + placeholder: 'My Environment', + defaultValue: 'My Environment', + confirmText: 'Create', + }); + if (name == null) return null; + + return createWorkspaceModel({ + model: 'environment', + name, + variables: [], + workspaceId, + base: false, + }); + }, + onSuccess: async (environmentId) => { + if (environmentId == null) { + return; // Was not created + } + + console.log('NAVIGATING', jotaiStore.get(activeWorkspaceIdAtom), environmentId); + setWorkspaceSearchParams({ environment_id: environmentId }); + }, +}); diff --git a/src-web/components/CommandPaletteDialog.tsx b/src-web/components/CommandPaletteDialog.tsx index 1faa30671..1010a0452 100644 --- a/src-web/components/CommandPaletteDialog.tsx +++ b/src-web/components/CommandPaletteDialog.tsx @@ -5,6 +5,7 @@ import { useAtomValue } from 'jotai'; import type { KeyboardEvent, ReactNode } from 'react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createFolder } from '../commands/commands'; +import { createEnvironmentAndActivate } from '../commands/createEnvironment'; import { openSettings } from '../commands/openSettings'; import { switchWorkspace } from '../commands/switchWorkspace'; import { useActiveCookieJar } from '../hooks/useActiveCookieJar'; @@ -12,7 +13,6 @@ import { useActiveEnvironment } from '../hooks/useActiveEnvironment'; import { useActiveRequest } from '../hooks/useActiveRequest'; import { activeWorkspaceIdAtom } from '../hooks/useActiveWorkspace'; import { useAllRequests } from '../hooks/useAllRequests'; -import { useCreateEnvironment } from '../hooks/useCreateEnvironment'; import { useCreateWorkspace } from '../hooks/useCreateWorkspace'; import { useDebouncedState } from '../hooks/useDebouncedState'; import { useEnvironmentsBreakdown } from '../hooks/useEnvironmentsBreakdown'; @@ -72,7 +72,6 @@ export function CommandPaletteDialog({ onClose }: { onClose: () => void }) { const activeCookieJar = useActiveCookieJar(); const [recentRequests] = useRecentRequests(); const [, setSidebarHidden] = useSidebarHidden(); - const { mutate: createEnvironment } = useCreateEnvironment(); const { mutate: sendRequest } = useSendAnyHttpRequest(); const workspaceCommands = useMemo(() => { @@ -139,7 +138,7 @@ export function CommandPaletteDialog({ onClose }: { onClose: () => void }) { { key: 'environment.create', label: 'Create Environment', - onSelect: () => createEnvironment(baseEnvironment), + onSelect: () => createEnvironmentAndActivate.mutate(baseEnvironment), }, { key: 'sidebar.toggle', @@ -190,7 +189,6 @@ export function CommandPaletteDialog({ onClose }: { onClose: () => void }) { activeEnvironment, activeRequest, baseEnvironment, - createEnvironment, createWorkspace, httpRequestActions, sendRequest, diff --git a/src-web/components/EnvironmentEditDialog.tsx b/src-web/components/EnvironmentEditDialog.tsx index d9bccdfed..f8d772ad2 100644 --- a/src-web/components/EnvironmentEditDialog.tsx +++ b/src-web/components/EnvironmentEditDialog.tsx @@ -4,7 +4,7 @@ import type { GenericCompletionOption } from '@yaakapp-internal/plugins'; import classNames from 'classnames'; import type { ReactNode } from 'react'; import React, { useCallback, useMemo, useState } from 'react'; -import { useCreateEnvironment } from '../hooks/useCreateEnvironment'; +import { createEnvironmentAndActivate } from '../commands/createEnvironment'; import { useEnvironmentsBreakdown } from '../hooks/useEnvironmentsBreakdown'; import { useIsEncryptionEnabled } from '../hooks/useIsEncryptionEnabled'; import { useKeyValue } from '../hooks/useKeyValue'; @@ -41,7 +41,6 @@ interface Props { } export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) { - const createEnvironment = useCreateEnvironment(); const { baseEnvironment, otherBaseEnvironments, subEnvironments, allEnvironments } = useEnvironmentsBreakdown(); const [selectedEnvironmentId, setSelectedEnvironmentId] = useState( @@ -55,7 +54,7 @@ export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) { const handleCreateEnvironment = async () => { if (baseEnvironment == null) return; - const id = await createEnvironment.mutateAsync(baseEnvironment); + const id = await createEnvironmentAndActivate.mutateAsync(baseEnvironment); if (id != null) setSelectedEnvironmentId(id); }; @@ -162,30 +161,30 @@ export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) { }; const EnvironmentEditor = function ({ - environment: activeEnvironment, + environment: selectedEnvironment, className, }: { environment: Environment; className?: string; }) { - const activeWorkspaceId = activeEnvironment.workspaceId; + const workspaceId = selectedEnvironment.workspaceId; const isEncryptionEnabled = useIsEncryptionEnabled(); const valueVisibility = useKeyValue({ namespace: 'global', - key: ['environmentValueVisibility', activeWorkspaceId], + key: ['environmentValueVisibility', workspaceId], fallback: false, }); const { allEnvironments } = useEnvironmentsBreakdown(); const handleChange = useCallback( - (variables: PairWithId[]) => patchModel(activeEnvironment, { variables }), - [activeEnvironment], + (variables: PairWithId[]) => patchModel(selectedEnvironment, { variables }), + [selectedEnvironment], ); const [forceUpdateKey, regenerateForceUpdateKey] = useRandomKey(); // Gather a list of env names from other environments to help the user get them aligned const nameAutocomplete = useMemo(() => { const options: GenericCompletionOption[] = []; - if (activeEnvironment.base) { + if (selectedEnvironment.base) { return { options }; } @@ -195,7 +194,7 @@ const EnvironmentEditor = function ({ const containingEnvs = allEnvironments.filter((e) => e.variables.some((v) => v.name === name), ); - const isAlreadyInActive = containingEnvs.find((e) => e.id === activeEnvironment.id); + const isAlreadyInActive = containingEnvs.find((e) => e.id === selectedEnvironment.id); if (isAlreadyInActive) continue; options.push({ label: name, @@ -204,7 +203,7 @@ const EnvironmentEditor = function ({ }); } return { options }; - }, [activeEnvironment.base, activeEnvironment.id, allEnvironments]); + }, [selectedEnvironment.base, selectedEnvironment.id, allEnvironments]); const validateName = useCallback((name: string) => { // Empty just means the variable doesn't have a name yet and is unusable @@ -217,11 +216,11 @@ const EnvironmentEditor = function ({ if (!isEncryptionEnabled) { return true; } else { - return !activeEnvironment.variables.every( + return !selectedEnvironment.variables.every( (v) => v.value === '' || analyzeTemplate(v.value) !== 'insecure', ); } - }, [activeEnvironment.variables, isEncryptionEnabled]); + }, [selectedEnvironment.variables, isEncryptionEnabled]); const encryptEnvironment = (environment: Environment) => { withEncryptionEnabled(async () => { @@ -238,10 +237,10 @@ const EnvironmentEditor = function ({ return ( -
{activeEnvironment?.name}
+
{selectedEnvironment?.name}
{isEncryptionEnabled ? ( promptToEncrypt ? ( - encryptEnvironment(activeEnvironment)}> + encryptEnvironment(selectedEnvironment)}> Encrypt All Variables ) : ( @@ -257,9 +256,9 @@ const EnvironmentEditor = function ({ )}
- {activeEnvironment.public && promptToEncrypt && ( + {selectedEnvironment.public && promptToEncrypt && ( @@ -277,11 +276,15 @@ const EnvironmentEditor = function ({ valueType={valueType} valueAutocompleteVariables valueAutocompleteFunctions - forcedEnvironmentId={activeEnvironment.id} - forceUpdateKey={`${activeEnvironment.id}::${forceUpdateKey}`} - pairs={activeEnvironment.variables} + forceUpdateKey={`${selectedEnvironment.id}::${forceUpdateKey}`} + pairs={selectedEnvironment.variables} onChange={handleChange} - stateKey={`environment.${activeEnvironment.id}`} + stateKey={`environment.${selectedEnvironment.id}`} + forcedEnvironmentId={ + // Editing the base environment should resolve variables using the active environment. + // Editing a sub environment should resolve variables as if it's the active environment + selectedEnvironment.base ? undefined : selectedEnvironment.id + } />
diff --git a/src-web/hooks/useCreateEnvironment.ts b/src-web/hooks/useCreateEnvironment.ts deleted file mode 100644 index 34f4a923b..000000000 --- a/src-web/hooks/useCreateEnvironment.ts +++ /dev/null @@ -1,50 +0,0 @@ -import type { Environment } from '@yaakapp-internal/models'; -import { createWorkspaceModel } from '@yaakapp-internal/models'; -import { useAtomValue } from 'jotai'; -import { showPrompt } from '../lib/prompt'; -import { setWorkspaceSearchParams } from '../lib/setWorkspaceSearchParams'; -import { activeWorkspaceIdAtom } from './useActiveWorkspace'; -import { useFastMutation } from './useFastMutation'; - -export function useCreateEnvironment() { - const workspaceId = useAtomValue(activeWorkspaceIdAtom); - - return useFastMutation({ - mutationKey: ['create_environment', workspaceId], - mutationFn: async (baseEnvironment) => { - if (baseEnvironment == null) { - throw new Error('No base environment passed'); - } - - if (workspaceId == null) { - throw new Error('Cannot create environment when no active workspace'); - } - - const name = await showPrompt({ - id: 'new-environment', - title: 'New Environment', - description: 'Create multiple environments with different sets of variables', - label: 'Name', - placeholder: 'My Environment', - defaultValue: 'My Environment', - confirmText: 'Create', - }); - if (name == null) return null; - - return createWorkspaceModel({ - model: 'environment', - name, - variables: [], - workspaceId, - base: false, - }); - }, - onSuccess: async (environmentId) => { - if (environmentId == null) { - return; // Was not created - } - - setWorkspaceSearchParams({ environment_id: environmentId }); - }, - }); -} From a05679fd931dd41d3fbc4e41e7374e29cdc86672 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 12:31:46 -0700 Subject: [PATCH 186/996] Bump vite from 6.2.6 to 6.2.7 in /src-web (#205) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src-web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-web/package.json b/src-web/package.json index 9db492683..520ecbea5 100644 --- a/src-web/package.json +++ b/src-web/package.json @@ -88,7 +88,7 @@ "postcss": "^8.4.45", "postcss-nesting": "^13.0.0", "tailwindcss": "^3.4.10", - "vite": "6.2.6", + "vite": "6.2.7", "vite-plugin-static-copy": "^2.2.0", "vite-plugin-svgr": "^4.3.0", "vite-plugin-top-level-await": "^1.5.0", From 763a60982aa354daafb6cde9bc2df25b2e0e7e2d Mon Sep 17 00:00:00 2001 From: Walyson G Oliveira Date: Fri, 16 May 2025 16:37:00 -0300 Subject: [PATCH 187/996] Adjusting the JSON viewing response to accept accentuation (#203) --- src-web/components/responseViewers/TextViewer.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src-web/components/responseViewers/TextViewer.tsx b/src-web/components/responseViewers/TextViewer.tsx index b8f141a2e..bb8695cb1 100644 --- a/src-web/components/responseViewers/TextViewer.tsx +++ b/src-web/components/responseViewers/TextViewer.tsx @@ -116,11 +116,14 @@ export function TextViewer({ language, text, responseId, requestId, pretty, clas body = formattedBody.data; } + // Decode unicode sequences in the text to readable characters + const decodedBodyText = unescape(body.replace(/\\u/g, '%u')) || body; + return ( ); } + From 3808215210622fd171601d493e66e6bd1e2dae55 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 16 May 2025 12:42:08 -0700 Subject: [PATCH 188/996] Better unicode un-escaping --- package-lock.json | 8 ++++---- .../components/responseViewers/TextViewer.tsx | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 63ee37488..83cb8d268 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14044,7 +14044,7 @@ "postcss": "^8.4.45", "postcss-nesting": "^13.0.0", "tailwindcss": "^3.4.10", - "vite": "6.2.6", + "vite": "6.2.7", "vite-plugin-static-copy": "^2.2.0", "vite-plugin-svgr": "^4.3.0", "vite-plugin-top-level-await": "^1.5.0", @@ -14584,9 +14584,9 @@ } }, "src-web/node_modules/vite": { - "version": "6.2.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.6.tgz", - "integrity": "sha512-9xpjNl3kR4rVDZgPNdTL0/c6ao4km69a/2ihNQbcANz8RuCOK3hQBmLSJf3bRKVQjVMda+YvizNE8AwvogcPbw==", + "version": "6.2.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.7.tgz", + "integrity": "sha512-qg3LkeuinTrZoJHHF94coSaTfIPyBYoywp+ys4qu20oSJFbKMYoIJo0FWJT9q6Vp49l6z9IsJRbHdcGtiKbGoQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/src-web/components/responseViewers/TextViewer.tsx b/src-web/components/responseViewers/TextViewer.tsx index bb8695cb1..bf99c2020 100644 --- a/src-web/components/responseViewers/TextViewer.tsx +++ b/src-web/components/responseViewers/TextViewer.tsx @@ -116,14 +116,16 @@ export function TextViewer({ language, text, responseId, requestId, pretty, clas body = formattedBody.data; } - // Decode unicode sequences in the text to readable characters - const decodedBodyText = unescape(body.replace(/\\u/g, '%u')) || body; + // Decode unicode sequences in the text to readable characters + if (pretty) { + body = decodeUnicodeLiterals(body); + } return ( { + const charCode = parseInt(hex, 16); + return String.fromCharCode(charCode); + }); + return decoded; +} From 42e70b941d7f918b5d0a4dc8aff8de583045ec65 Mon Sep 17 00:00:00 2001 From: Hao Xiang Date: Sat, 17 May 2025 03:53:53 +0800 Subject: [PATCH 189/996] fix proto to json-schema (#194) --- src-tauri/yaak-grpc/src/json_schema.rs | 475 ++++++++++++++++++------- 1 file changed, 351 insertions(+), 124 deletions(-) diff --git a/src-tauri/yaak-grpc/src/json_schema.rs b/src-tauri/yaak-grpc/src/json_schema.rs index b915c6c00..685b8e11c 100644 --- a/src-tauri/yaak-grpc/src/json_schema.rs +++ b/src-tauri/yaak-grpc/src/json_schema.rs @@ -1,16 +1,256 @@ -use prost_reflect::{DescriptorPool, MessageDescriptor}; -use prost_types::field_descriptor_proto; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use prost_reflect::{DescriptorPool, FieldDescriptor, MessageDescriptor}; +use std::collections::{HashMap, HashSet, VecDeque}; -#[derive(Default, Serialize, Deserialize)] +pub fn message_to_json_schema(_: &DescriptorPool, root_msg: MessageDescriptor) -> JsonSchemaEntry { + JsonSchemaGenerator::generate_json_schema(root_msg) +} + +struct JsonSchemaGenerator { + msg_mapping: HashMap, +} + +impl JsonSchemaGenerator { + pub fn new() -> Self { + JsonSchemaGenerator { + msg_mapping: HashMap::new(), + } + } + + pub fn generate_json_schema(msg: MessageDescriptor) -> JsonSchemaEntry { + let generator = JsonSchemaGenerator::new(); + generator.scan_root(msg) + } + + fn add_message(&mut self, msg: &MessageDescriptor) { + let name = msg.full_name().to_string(); + if self.msg_mapping.contains_key(&name) { + return; + } + self.msg_mapping.insert(name.clone(), JsonSchemaEntry::object()); + } + + pub fn scan_root(mut self, root_msg: MessageDescriptor) -> JsonSchemaEntry { + self.init_structure(root_msg.clone()); + self.fill_properties(root_msg.clone()); + + let mut root = self.msg_mapping.remove(root_msg.full_name()).unwrap(); + + if self.msg_mapping.len() > 0 { + root.defs = Some(self.msg_mapping); + } + root + } + + fn fill_properties(&mut self, root_msg: MessageDescriptor) { + let root_name = root_msg.full_name().to_string(); + + let mut visited = HashSet::new(); + let mut msg_queue = VecDeque::new(); + msg_queue.push_back(root_msg); + + while !msg_queue.is_empty() { + let msg = msg_queue.pop_front().unwrap(); + let msg_name = msg.full_name(); + if visited.contains(msg_name) { + continue; + } + + visited.insert(msg_name.to_string()); + + let entry = self.msg_mapping.get_mut(msg_name).unwrap(); + + for field in msg.fields() { + let field_name = field.name().to_string(); + + if matches!(field.cardinality(), prost_reflect::Cardinality::Required) { + entry.add_required(field_name.clone()); + } + + if let Some(oneof) = field.containing_oneof() { + for oneof_field in oneof.fields() { + if let Some(fm) = is_message_field(&oneof_field) { + msg_queue.push_back(fm); + } + entry.add_property( + oneof_field.name().to_string(), + field_to_type_or_ref(&root_name, oneof_field), + ); + } + continue; + } + + let (field_type, nest_msg) = { + if let Some(fm) = is_message_field(&field) { + if field.is_list() { + // repeated message type + ( + JsonSchemaEntry::array(field_to_type_or_ref(&root_name, field)), + Some(fm), + ) + } else if field.is_map() { + let value_field = fm.get_field_by_name("value").unwrap(); + + if let Some(fm) = is_message_field(&value_field) { + ( + JsonSchemaEntry::map(field_to_type_or_ref( + &root_name, + value_field, + )), + Some(fm), + ) + } else { + ( + JsonSchemaEntry::map(field_to_type_or_ref( + &root_name, + value_field, + )), + None, + ) + } + } else { + (field_to_type_or_ref(&root_name, field), Some(fm)) + } + } else { + if field.is_list() { + // repeated scalar type + (JsonSchemaEntry::array(field_to_type_or_ref(&root_name, field)), None) + } else { + (field_to_type_or_ref(&root_name, field), None) + } + } + }; + + if let Some(fm) = nest_msg { + msg_queue.push_back(fm); + } + + entry.add_property(field_name, field_type); + } + } + } + + fn init_structure(&mut self, root_msg: MessageDescriptor) { + let mut visited = HashSet::new(); + let mut msg_queue = VecDeque::new(); + msg_queue.push_back(root_msg.clone()); + + // level traversal, to make sure all message type is defined before used + while !msg_queue.is_empty() { + let msg = msg_queue.pop_front().unwrap(); + let name = msg.full_name(); + if visited.contains(name) { + continue; + } + visited.insert(name.to_string()); + self.add_message(&msg); + + for child in msg.child_messages() { + if child.is_map_entry() { + // for field with map type, there will be a child message type *Entry generated + // just skip it + continue; + } + + self.add_message(&child); + msg_queue.push_back(child); + } + + for field in msg.fields() { + if let Some(oneof) = field.containing_oneof() { + for oneof_field in oneof.fields() { + if let Some(fm) = is_message_field(&oneof_field) { + self.add_message(&fm); + msg_queue.push_back(fm); + } + } + continue; + } + if field.is_map() { + // key is always scalar type, so no need to process + // value can be any type, so need to unpack value type + let map_field_msg = is_message_field(&field).unwrap(); + let map_value_field = map_field_msg.get_field_by_name("value").unwrap(); + if let Some(value_fm) = is_message_field(&map_value_field) { + self.add_message(&value_fm); + msg_queue.push_back(value_fm); + } + continue; + } + if let Some(fm) = is_message_field(&field) { + self.add_message(&fm); + msg_queue.push_back(fm); + } + } + } + } +} + +fn field_to_type_or_ref(root_name: &str, field: FieldDescriptor) -> JsonSchemaEntry { + match field.kind() { + prost_reflect::Kind::Bool => JsonSchemaEntry::boolean(), + prost_reflect::Kind::Double => JsonSchemaEntry::number("double"), + prost_reflect::Kind::Float => JsonSchemaEntry::number("float"), + prost_reflect::Kind::Int32 => JsonSchemaEntry::number("int32"), + prost_reflect::Kind::Int64 => JsonSchemaEntry::string_with_format("int64"), + prost_reflect::Kind::Uint32 => JsonSchemaEntry::number("int64"), + prost_reflect::Kind::Uint64 => JsonSchemaEntry::string_with_format("uint64"), + prost_reflect::Kind::Sint32 => JsonSchemaEntry::number("sint32"), + prost_reflect::Kind::Sint64 => JsonSchemaEntry::string_with_format("sint64"), + prost_reflect::Kind::Fixed32 => JsonSchemaEntry::number("int64"), + prost_reflect::Kind::Fixed64 => JsonSchemaEntry::string_with_format("fixed64"), + prost_reflect::Kind::Sfixed32 => JsonSchemaEntry::number("sfixed32"), + prost_reflect::Kind::Sfixed64 => JsonSchemaEntry::string_with_format("sfixed64"), + prost_reflect::Kind::String => JsonSchemaEntry::string(), + prost_reflect::Kind::Bytes => JsonSchemaEntry::string_with_format("byte"), + prost_reflect::Kind::Enum(enums) => { + let values = enums.values().map(|v| v.name().to_string()).collect::>(); + JsonSchemaEntry::enums(values) + } + prost_reflect::Kind::Message(fm) => { + let field_type_full_name = fm.full_name(); + match field_type_full_name { + // [Protocol Buffers Well-Known Types]: https://protobuf.dev/reference/protobuf/google.protobuf/ + "google.protobuf.FieldMask" => JsonSchemaEntry::string(), + "google.protobuf.Timestamp" => JsonSchemaEntry::string_with_format("date-time"), + "google.protobuf.Duration" => JsonSchemaEntry::string(), + "google.protobuf.StringValue" => JsonSchemaEntry::string(), + "google.protobuf.BytesValue" => JsonSchemaEntry::string_with_format("byte"), + "google.protobuf.Int32Value" => JsonSchemaEntry::number("int32"), + "google.protobuf.UInt32Value" => JsonSchemaEntry::string_with_format("int64"), + "google.protobuf.Int64Value" => JsonSchemaEntry::string_with_format("int64"), + "google.protobuf.UInt64Value" => JsonSchemaEntry::string_with_format("uint64"), + "google.protobuf.FloatValue" => JsonSchemaEntry::number("float"), + "google.protobuf.DoubleValue" => JsonSchemaEntry::number("double"), + "google.protobuf.BoolValue" => JsonSchemaEntry::boolean(), + "google.protobuf.Empty" => JsonSchemaEntry::default(), + "google.protobuf.Struct" => JsonSchemaEntry::object(), + "google.protobuf.ListValue" => JsonSchemaEntry::array(JsonSchemaEntry::default()), + "google.protobuf.NullValue" => JsonSchemaEntry::null(), + name @ _ if name == root_name => JsonSchemaEntry::root_reference(), + _ => JsonSchemaEntry::reference(fm.full_name()), + } + } + } +} + +fn is_message_field(field: &FieldDescriptor) -> Option { + match field.kind() { + prost_reflect::Kind::Message(m) => Some(m), + _ => None, + } +} + +#[derive(Default, serde::Serialize)] #[serde(default, rename_all = "camelCase")] pub struct JsonSchemaEntry { #[serde(skip_serializing_if = "Option::is_none")] title: Option, - #[serde(rename = "type")] - type_: JsonType, + #[serde(rename = "type", skip_serializing_if = "Option::is_none")] + type_: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + format: Option, #[serde(skip_serializing_if = "Option::is_none")] description: Option, @@ -21,15 +261,115 @@ pub struct JsonSchemaEntry { #[serde(rename = "enum", skip_serializing_if = "Option::is_none")] enum_: Option>, - /// Don't allow any other properties in the object - additional_properties: bool, + // for map type + #[serde(skip_serializing_if = "Option::is_none")] + additional_properties: Option>, - /// Set all properties to required + // Set all properties to required #[serde(skip_serializing_if = "Option::is_none")] required: Option>, #[serde(skip_serializing_if = "Option::is_none")] items: Option>, + + #[serde(skip_serializing_if = "Option::is_none", rename = "$defs")] + defs: Option>, + + #[serde(skip_serializing_if = "Option::is_none", rename = "$ref")] + ref_: Option, +} + +impl JsonSchemaEntry { + pub fn add_property(&mut self, name: String, entry: JsonSchemaEntry) { + if self.properties.is_none() { + self.properties = Some(HashMap::new()); + } + self.properties.as_mut().unwrap().insert(name, entry); + } + + pub fn add_required(&mut self, name: String) { + if self.required.is_none() { + self.required = Some(Vec::new()); + } + self.required.as_mut().unwrap().push(name); + } +} + +impl JsonSchemaEntry { + pub fn object() -> Self { + JsonSchemaEntry { + type_: Some(JsonType::Object), + ..Default::default() + } + } + pub fn boolean() -> Self { + JsonSchemaEntry { + type_: Some(JsonType::Boolean), + ..Default::default() + } + } + pub fn number>(format: S) -> Self { + JsonSchemaEntry { + type_: Some(JsonType::Number), + format: Some(format.into()), + ..Default::default() + } + } + pub fn string() -> Self { + JsonSchemaEntry { + type_: Some(JsonType::String), + ..Default::default() + } + } + + pub fn string_with_format>(format: S) -> Self { + JsonSchemaEntry { + type_: Some(JsonType::String), + format: Some(format.into()), + ..Default::default() + } + } + pub fn reference>(ref_: S) -> Self { + JsonSchemaEntry { + ref_: Some(format!("#/$defs/{}", ref_.as_ref())), + ..Default::default() + } + } + pub fn root_reference() -> Self{ + JsonSchemaEntry { + ref_: Some("#".to_string()), + ..Default::default() + } + } + pub fn array(item: JsonSchemaEntry) -> Self { + JsonSchemaEntry { + type_: Some(JsonType::Array), + items: Some(Box::new(item)), + ..Default::default() + } + } + pub fn enums(enums: Vec) -> Self { + JsonSchemaEntry { + type_: Some(JsonType::String), + enum_: Some(enums), + ..Default::default() + } + } + + pub fn map(value_type: JsonSchemaEntry) -> Self { + JsonSchemaEntry { + type_: Some(JsonType::Object), + additional_properties: Some(Box::new(value_type)), + ..Default::default() + } + } + + pub fn null() -> Self { + JsonSchemaEntry { + type_: Some(JsonType::Null), + ..Default::default() + } + } } enum JsonType { @@ -49,7 +389,7 @@ impl Default for JsonType { } impl serde::Serialize for JsonType { - fn serialize(&self, serializer: S) -> Result + fn serialize(&self, serializer: S) -> std::result::Result where S: serde::Serializer, { @@ -64,116 +404,3 @@ impl serde::Serialize for JsonType { } } } - -impl<'de> serde::Deserialize<'de> for JsonType { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let s = String::deserialize(deserializer)?; - match s.as_str() { - "string" => Ok(JsonType::String), - "number" => Ok(JsonType::Number), - "object" => Ok(JsonType::Object), - "array" => Ok(JsonType::Array), - "boolean" => Ok(JsonType::Boolean), - "null" => Ok(JsonType::Null), - _ => Ok(JsonType::_UNKNOWN), - } - } -} - -pub fn message_to_json_schema( - pool: &DescriptorPool, - message: MessageDescriptor, -) -> JsonSchemaEntry { - let mut schema = JsonSchemaEntry { - title: Some(message.name().to_string()), - type_: JsonType::Object, // Messages are objects - ..Default::default() - }; - - let mut properties = HashMap::new(); - message.fields().for_each(|f| match f.kind() { - prost_reflect::Kind::Message(m) => { - properties.insert(f.name().to_string(), message_to_json_schema(pool, m)); - } - prost_reflect::Kind::Enum(e) => { - properties.insert( - f.name().to_string(), - JsonSchemaEntry { - type_: map_proto_type_to_json_type(f.field_descriptor_proto().r#type()), - enum_: Some(e.values().map(|v| v.name().to_string()).collect::>()), - ..Default::default() - }, - ); - } - _ => { - // TODO: Handle repeated label - match f.field_descriptor_proto().label() { - field_descriptor_proto::Label::Repeated => { - // TODO: Handle more complex repeated types. This just handles primitives for now - properties.insert( - f.name().to_string(), - JsonSchemaEntry { - type_: JsonType::Array, - items: Some(Box::new(JsonSchemaEntry { - type_: map_proto_type_to_json_type( - f.field_descriptor_proto().r#type(), - ), - ..Default::default() - })), - ..Default::default() - }, - ); - } - _ => { - // Regular JSON field - properties.insert( - f.name().to_string(), - JsonSchemaEntry { - type_: map_proto_type_to_json_type(f.field_descriptor_proto().r#type()), - ..Default::default() - }, - ); - } - }; - } - }); - - schema.properties = Some(properties); - - // All proto 3 fields are optional, so maybe we could - // make this a setting? - // schema.required = Some( - // message - // .fields() - // .map(|f| f.name().to_string()) - // .collect::>(), - // ); - - schema -} - -fn map_proto_type_to_json_type(proto_type: field_descriptor_proto::Type) -> JsonType { - match proto_type { - field_descriptor_proto::Type::Double => JsonType::Number, - field_descriptor_proto::Type::Float => JsonType::Number, - field_descriptor_proto::Type::Int64 => JsonType::Number, - field_descriptor_proto::Type::Uint64 => JsonType::Number, - field_descriptor_proto::Type::Int32 => JsonType::Number, - field_descriptor_proto::Type::Fixed64 => JsonType::Number, - field_descriptor_proto::Type::Fixed32 => JsonType::Number, - field_descriptor_proto::Type::Bool => JsonType::Boolean, - field_descriptor_proto::Type::String => JsonType::String, - field_descriptor_proto::Type::Group => JsonType::_UNKNOWN, - field_descriptor_proto::Type::Message => JsonType::Object, - field_descriptor_proto::Type::Bytes => JsonType::String, - field_descriptor_proto::Type::Uint32 => JsonType::Number, - field_descriptor_proto::Type::Enum => JsonType::String, - field_descriptor_proto::Type::Sfixed32 => JsonType::Number, - field_descriptor_proto::Type::Sfixed64 => JsonType::Number, - field_descriptor_proto::Type::Sint32 => JsonType::Number, - field_descriptor_proto::Type::Sint64 => JsonType::Number, - } -} From 432b366105be34d8d83b3f1ee351db268007f792 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 16 May 2025 13:00:50 -0700 Subject: [PATCH 190/996] Fix grpc/ws events error --- src-web/hooks/usePinnedGrpcConnection.ts | 5 +++++ src-web/hooks/usePinnedWebsocketConnection.ts | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src-web/hooks/usePinnedGrpcConnection.ts b/src-web/hooks/usePinnedGrpcConnection.ts index af812d5de..125105238 100644 --- a/src-web/hooks/usePinnedGrpcConnection.ts +++ b/src-web/hooks/usePinnedGrpcConnection.ts @@ -62,6 +62,11 @@ export function useGrpcEvents(connectionId: string | null) { const events = useAtomValue(grpcEventsAtom); useEffect(() => { + if (connectionId == null) { + replaceModelsInStore('grpc_event', []); + return; + } + invoke('plugin:yaak-models|grpc_events', { connectionId }).then((events) => { replaceModelsInStore('grpc_event', events); }); diff --git a/src-web/hooks/usePinnedWebsocketConnection.ts b/src-web/hooks/usePinnedWebsocketConnection.ts index 698d90273..491e4524e 100644 --- a/src-web/hooks/usePinnedWebsocketConnection.ts +++ b/src-web/hooks/usePinnedWebsocketConnection.ts @@ -1,6 +1,10 @@ import { invoke } from '@tauri-apps/api/core'; import type { WebsocketConnection, WebsocketEvent } from '@yaakapp-internal/models'; -import { replaceModelsInStore , websocketConnectionsAtom, websocketEventsAtom } from '@yaakapp-internal/models'; +import { + replaceModelsInStore, + websocketConnectionsAtom, + websocketEventsAtom, +} from '@yaakapp-internal/models'; import { atom, useAtomValue } from 'jotai'; import { useEffect } from 'react'; import { atomWithKVStorage } from '../lib/atoms/atomWithKVStorage'; @@ -45,6 +49,11 @@ export function useWebsocketEvents(connectionId: string | null) { const events = useAtomValue(websocketEventsAtom); useEffect(() => { + if (connectionId == null) { + replaceModelsInStore('websocket_event', []); + return; + } + invoke('plugin:yaak-models|websocket_events', { connectionId }).then( (events) => replaceModelsInStore('websocket_event', events), ); From be82b67ed3eaf877bf0d270a532402d2263f8975 Mon Sep 17 00:00:00 2001 From: Desperate Necromancer <57827456+AlphaNecron@users.noreply.github.com> Date: Sat, 17 May 2025 03:33:59 +0700 Subject: [PATCH 191/996] Allow disabling window decorations/controls (#176) Co-authored-by: Gregory Schier --- .../20250302041707_hide-window-controls.sql | 2 + src-tauri/yaak-models/bindings/gen_models.ts | 2 +- src-tauri/yaak-models/bindings/gen_util.ts | 12 ++--- src-tauri/yaak-models/src/models.rs | 4 ++ src-tauri/yaak-models/src/queries/settings.rs | 1 + src-web/components/HeaderSize.tsx | 46 ++++++++++++------- src-web/components/Settings/Settings.tsx | 7 +-- .../Settings/SettingsAppearance.tsx | 10 ++++ src-web/components/WindowControls.tsx | 13 +++--- src-web/components/core/Checkbox.tsx | 4 +- src-web/components/core/HotKey.tsx | 4 +- src-web/components/core/Select.tsx | 5 +- src-web/hooks/useHotKey.ts | 6 +-- src-web/hooks/useOsInfo.ts | 5 -- src-web/hooks/useStoplightsVisible.ts | 5 +- src-web/lib/constants.ts | 2 +- src-web/routes/__root.tsx | 5 +- 17 files changed, 75 insertions(+), 58 deletions(-) create mode 100644 src-tauri/migrations/20250302041707_hide-window-controls.sql delete mode 100644 src-web/hooks/useOsInfo.ts diff --git a/src-tauri/migrations/20250302041707_hide-window-controls.sql b/src-tauri/migrations/20250302041707_hide-window-controls.sql new file mode 100644 index 000000000..fb2017f44 --- /dev/null +++ b/src-tauri/migrations/20250302041707_hide-window-controls.sql @@ -0,0 +1,2 @@ +ALTER TABLE settings + ADD COLUMN hide_window_controls BOOLEAN DEFAULT FALSE NOT NULL; diff --git a/src-tauri/yaak-models/bindings/gen_models.ts b/src-tauri/yaak-models/bindings/gen_models.ts index e59ed39f9..7e5e0e609 100644 --- a/src-tauri/yaak-models/bindings/gen_models.ts +++ b/src-tauri/yaak-models/bindings/gen_models.ts @@ -58,7 +58,7 @@ export type ProxySetting = { "type": "enabled", disabled: boolean, http: string, export type ProxySettingAuth = { user: string, password: string, }; -export type Settings = { model: "settings", id: string, createdAt: string, updatedAt: string, appearance: string, editorFontSize: number, editorSoftWrap: boolean, interfaceFontSize: number, interfaceScale: number, openWorkspaceNewWindow: boolean | null, proxy: ProxySetting | null, themeDark: string, themeLight: string, updateChannel: string, editorKeymap: EditorKeymap, }; +export type Settings = { model: "settings", id: string, createdAt: string, updatedAt: string, appearance: string, editorFontSize: number, editorSoftWrap: boolean, hideWindowControls: boolean, interfaceFontSize: number, interfaceScale: number, openWorkspaceNewWindow: boolean | null, proxy: ProxySetting | null, themeDark: string, themeLight: string, updateChannel: string, editorKeymap: EditorKeymap, }; export type SyncState = { model: "sync_state", id: string, workspaceId: string, createdAt: string, updatedAt: string, flushedAt: string, modelId: string, checksum: string, relPath: string, syncDir: string, }; diff --git a/src-tauri/yaak-models/bindings/gen_util.ts b/src-tauri/yaak-models/bindings/gen_util.ts index a38424de1..482d19026 100644 --- a/src-tauri/yaak-models/bindings/gen_util.ts +++ b/src-tauri/yaak-models/bindings/gen_util.ts @@ -1,9 +1,9 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -import type { Environment } from "./gen_models"; -import type { Folder } from "./gen_models"; -import type { GrpcRequest } from "./gen_models"; -import type { HttpRequest } from "./gen_models"; -import type { WebsocketRequest } from "./gen_models"; -import type { Workspace } from "./gen_models"; +import type { Environment } from "./gen_models.js"; +import type { Folder } from "./gen_models.js"; +import type { GrpcRequest } from "./gen_models.js"; +import type { HttpRequest } from "./gen_models.js"; +import type { WebsocketRequest } from "./gen_models.js"; +import type { Workspace } from "./gen_models.js"; export type BatchUpsertResult = { workspaces: Array, environments: Array, folders: Array, httpRequests: Array, grpcRequests: Array, websocketRequests: Array, }; diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index 0a3f18204..7a5f24efa 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -105,6 +105,7 @@ pub struct Settings { pub appearance: String, pub editor_font_size: i32, pub editor_soft_wrap: bool, + pub hide_window_controls: bool, pub interface_font_size: i32, pub interface_scale: f32, pub open_workspace_new_window: Option, @@ -154,6 +155,7 @@ impl UpsertModelInfo for Settings { (EditorSoftWrap, self.editor_soft_wrap.into()), (InterfaceFontSize, self.interface_font_size.into()), (InterfaceScale, self.interface_scale.into()), + (HideWindowControls, self.hide_window_controls.into()), (OpenWorkspaceNewWindow, self.open_workspace_new_window.into()), (ThemeDark, self.theme_dark.as_str().into()), (ThemeLight, self.theme_light.as_str().into()), @@ -171,6 +173,7 @@ impl UpsertModelInfo for Settings { SettingsIden::EditorSoftWrap, SettingsIden::InterfaceFontSize, SettingsIden::InterfaceScale, + SettingsIden::HideWindowControls, SettingsIden::OpenWorkspaceNewWindow, SettingsIden::Proxy, SettingsIden::ThemeDark, @@ -200,6 +203,7 @@ impl UpsertModelInfo for Settings { proxy: proxy.map(|p| -> ProxySetting { serde_json::from_str(p.as_str()).unwrap() }), theme_dark: row.get("theme_dark")?, theme_light: row.get("theme_light")?, + hide_window_controls: row.get("hide_window_controls")?, update_channel: row.get("update_channel")?, }) } diff --git a/src-tauri/yaak-models/src/queries/settings.rs b/src-tauri/yaak-models/src/queries/settings.rs index 2bc7504a9..5635abd5f 100644 --- a/src-tauri/yaak-models/src/queries/settings.rs +++ b/src-tauri/yaak-models/src/queries/settings.rs @@ -23,6 +23,7 @@ impl<'a> DbContext<'a> { editor_soft_wrap: true, interface_font_size: 15, interface_scale: 1.0, + hide_window_controls: false, open_workspace_new_window: None, proxy: None, theme_dark: "yaak-dark".to_string(), diff --git a/src-web/components/HeaderSize.tsx b/src-web/components/HeaderSize.tsx index e3eb6cc0f..0aa769fd6 100644 --- a/src-web/components/HeaderSize.tsx +++ b/src-web/components/HeaderSize.tsx @@ -1,9 +1,8 @@ import { settingsAtom } from '@yaakapp-internal/models'; import classNames from 'classnames'; import { useAtomValue } from 'jotai'; -import type { HTMLAttributes, ReactNode } from 'react'; -import React from 'react'; -import { useOsInfo } from '../hooks/useOsInfo'; +import type { CSSProperties, HTMLAttributes, ReactNode } from 'react'; +import React, { useMemo } from 'react'; import { useStoplightsVisible } from '../hooks/useStoplightsVisible'; import { HEADER_SIZE_LG, HEADER_SIZE_MD, WINDOW_CONTROLS_WIDTH } from '../lib/constants'; import { WindowControls } from './WindowControls'; @@ -23,27 +22,42 @@ export function HeaderSize({ onlyXWindowControl, children, }: HeaderSizeProps) { - const osInfo = useOsInfo(); const settings = useAtomValue(settingsAtom); const stoplightsVisible = useStoplightsVisible(); + const finalStyle = useMemo(() => { + const s = { ...style }; + + // Set the height (use min-height because scaling font size may make it larger + if (size === 'md') s.minHeight = HEADER_SIZE_MD; + if (size === 'lg') s.minHeight = HEADER_SIZE_LG; + + // Add large padding for window controls + if (stoplightsVisible && !ignoreControlsSpacing) { + s.paddingLeft = 72 / settings.interfaceScale; + } else if (!stoplightsVisible && !ignoreControlsSpacing && !settings.hideWindowControls) { + s.paddingRight = WINDOW_CONTROLS_WIDTH; + } + + return s; + }, [ + ignoreControlsSpacing, + settings.hideWindowControls, + settings.interfaceScale, + size, + stoplightsVisible, + style, + ]); + return (
{/* NOTE: This needs display:grid or else the element shrinks (even though scrollable) */} diff --git a/src-web/components/Settings/Settings.tsx b/src-web/components/Settings/Settings.tsx index 9b5208a74..21d1888ce 100644 --- a/src-web/components/Settings/Settings.tsx +++ b/src-web/components/Settings/Settings.tsx @@ -1,9 +1,9 @@ import { useSearch } from '@tanstack/react-router'; import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; +import { type } from '@tauri-apps/plugin-os'; import classNames from 'classnames'; import React, { useState } from 'react'; import { useKeyPressEvent } from 'react-use'; -import { useOsInfo } from '../../hooks/useOsInfo'; import { capitalize } from '../../lib/capitalize'; import { HStack } from '../core/Stacks'; import { TabContent, Tabs } from '../core/Tabs/Tabs'; @@ -27,7 +27,6 @@ const tabs = [TAB_GENERAL, TAB_APPEARANCE, TAB_PROXY, TAB_PLUGINS, TAB_LICENSE] export type SettingsTab = (typeof tabs)[number]; export default function Settings({ hide }: Props) { - const osInfo = useOsInfo(); const { tab: tabFromQuery } = useSearch({ from: '/workspaces/$workspaceId/settings' }); const [tab, setTab] = useState(tabFromQuery); @@ -60,9 +59,7 @@ export default function Settings({ hide }: Props) { justifyContent="center" className="w-full h-full grid grid-cols-[1fr_auto] pointer-events-none" > -
- Settings -
+
Settings
)} diff --git a/src-web/components/Settings/SettingsAppearance.tsx b/src-web/components/Settings/SettingsAppearance.tsx index dbff98336..9fd37a077 100644 --- a/src-web/components/Settings/SettingsAppearance.tsx +++ b/src-web/components/Settings/SettingsAppearance.tsx @@ -18,6 +18,7 @@ import type { SelectProps } from '../core/Select'; import { Select } from '../core/Select'; import { Separator } from '../core/Separator'; import { HStack, VStack } from '../core/Stacks'; +import { type } from '@tauri-apps/plugin-os'; const fontSizeOptions = [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, @@ -122,6 +123,15 @@ export function SettingsAppearance() { onChange={(editorSoftWrap) => patchModel(settings, { editorSoftWrap })} /> + {type() !== 'macos' && ( + patchModel(settings, { hideWindowControls })} + /> + )} + { name: string; @@ -40,7 +40,6 @@ export function Select({ defaultValue, size = 'md', }: SelectProps) { - const osInfo = useOsInfo(); const [focused, setFocused] = useState(false); const id = `input-${name}`; const isInvalidSelection = options.find((o) => 'value' in o && o.value === value) == null; @@ -63,7 +62,7 @@ export function Select({ - {osInfo?.osType === 'macos' ? ( + {type() === 'macos' ? ( @@ -36,7 +35,7 @@ function RouteComponent() {
From 3e9037f70a24cb643a74e4a58f434148412152b6 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sat, 17 May 2025 06:06:36 -0700 Subject: [PATCH 192/996] No longer mark environments as external in Git --- src-web/components/GitCommitDialog.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src-web/components/GitCommitDialog.tsx b/src-web/components/GitCommitDialog.tsx index 92f73027d..65b02179b 100644 --- a/src-web/components/GitCommitDialog.tsx +++ b/src-web/components/GitCommitDialog.tsx @@ -70,8 +70,6 @@ export function GitCommitDialog({ syncDir, onDone, workspace }: Props) { allEntries.push(entry); if (entry.next == null && entry.prev == null) { externalEntries.push(entry); - } else if (entry.next?.model === 'environment' || entry.prev?.model === 'environment') { - externalEntries.push(entry); } else { yaakEntries.push(entry); } From 4ae7f99264d1ed71ed3154de1f2090c1160f4d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20L=C3=A9vesque?= Date: Sat, 17 May 2025 16:47:24 -0400 Subject: [PATCH 193/996] fix: Fixes the implicit OAuth flow not waiting for user to authenticate (#8) --- plugins/auth-oauth2/src/grants/implicit.ts | 24 ++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/plugins/auth-oauth2/src/grants/implicit.ts b/plugins/auth-oauth2/src/grants/implicit.ts index a54d1964e..592f875ff 100644 --- a/plugins/auth-oauth2/src/grants/implicit.ts +++ b/plugins/auth-oauth2/src/grants/implicit.ts @@ -31,7 +31,7 @@ export function getImplicit( } const authorizationUrl = new URL(`${authorizationUrlRaw ?? ''}`); - authorizationUrl.searchParams.set('response_type', 'code'); + authorizationUrl.searchParams.set('response_type', 'token'); authorizationUrl.searchParams.set('client_id', clientId); if (redirectUri) authorizationUrl.searchParams.set('redirect_uri', redirectUri); if (scope) authorizationUrl.searchParams.set('scope', scope); @@ -42,25 +42,33 @@ export function getImplicit( } const authorizationUrlStr = authorizationUrl.toString(); + let foundAccessToken = false; let { close } = await ctx.window.openUrl({ url: authorizationUrlStr, label: 'oauth-authorization-url', + async onClose() { + if (!foundAccessToken) { + reject(new Error('Authorization window closed')); + } + }, async onNavigate({ url: urlStr }) { const url = new URL(urlStr); if (url.searchParams.has('error')) { return reject(Error(`Failed to authorize: ${url.searchParams.get('error')}`)); } - // Close the window here, because we don't need it anymore - close(); - const hash = url.hash.slice(1); const params = new URLSearchParams(hash); - const idToken = params.get('id_token'); - if (idToken) { - params.set('access_token', idToken); - params.delete('id_token'); + + const accessToken = params.get('access_token'); + if (!accessToken) { + return; } + foundAccessToken = true; + + // Close the window here, because we don't need it anymore + close(); + const response = Object.fromEntries(params) as unknown as AccessTokenRawResponse; try { resolve(await storeToken(ctx, contextId, response)); From 409620f5331c9823405a6173f2fb9959a0f407ad Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 19 May 2025 13:37:12 -0700 Subject: [PATCH 194/996] More advanced template grammar Fixes https://feedback.yaak.app/p/cannot-escape-call-to-variable-in-json-body --- .../components/core/Editor/twig/highlight.ts | 13 +++- .../components/core/Editor/twig/twig.grammar | 69 ++++++++++++++++--- .../components/core/Editor/twig/twig.terms.ts | 15 ++-- src-web/components/core/Editor/twig/twig.ts | 24 ++++--- 4 files changed, 95 insertions(+), 26 deletions(-) diff --git a/src-web/components/core/Editor/twig/highlight.ts b/src-web/components/core/Editor/twig/highlight.ts index 0d3b3834f..e33381eaf 100644 --- a/src-web/components/core/Editor/twig/highlight.ts +++ b/src-web/components/core/Editor/twig/highlight.ts @@ -1,7 +1,14 @@ import { styleTags, tags as t } from '@lezer/highlight'; export const highlight = styleTags({ - TagOpen: t.tagName, - TagClose: t.tagName, - TagContent: t.keyword, + "${[": t.bracket, + "]}": t.bracket, + "(": t.bracket, + ")": t.bracket, + "=": t.bracket, + ",": t.bracket, + Tag: t.keyword, + Identifier: t.variableName, + ChainedIdentifier: t.variableName, + Boolean: t.bool, }); diff --git a/src-web/components/core/Editor/twig/twig.grammar b/src-web/components/core/Editor/twig/twig.grammar index 5706e2003..6d31100db 100644 --- a/src-web/components/core/Editor/twig/twig.grammar +++ b/src-web/components/core/Editor/twig/twig.grammar @@ -1,17 +1,70 @@ -@top Template { (Tag | Text)* } +@precedence { + top, + mid, + lesser +} + +@top Template { (Tag | PlainText)* } + +@skip { space } + +Tag { "${[" expression* "]}" } + +commaSep { "" | content ("," content?)* } + +expression { + Function | + Assignment | + Identifier | + ChainedIdentifier | + basicType | + hashStructure +} + +basicType { + String | + Boolean | + Number +} -@local tokens { - TagClose { "]}" } - @else TagContent +functionParam { + Identifier | + Assignment | + basicType } -@skip { } { - TagOpen { "${[" } - Tag { TagOpen (TagContent)+ TagClose } +FunctionParamList { + "(" commaSep ")" } +Assignment { Identifier "=" expression } + +Function { (Identifier | ChainedIdentifier) !top FunctionParamList} + @tokens { - Text { ![$] Text? | "$" (@eof | ![{] Text?) } + PlainText { ![$] PlainText? | "$" (@eof | ![{[] PlainText?) } + + Identifier { $[a-zA-Z_\-0-9]+ } + ChainedIdentifier { Identifier ("." Identifier)+ } + + hashStructure { "{" | "}" | ":" | ","} + + Boolean { "true" | "false" } + String { ("'" (![\\'] | "\\" _)* "'"?) | ("\"" (![\\"] | "\\" _)* "\""?) } + Number { '-'? int frac? } + int { '0' | $[1-9] @digit* } + frac { '.' @digit+ } + + @precedence { PlainText, Boolean, Number, ChainedIdentifier, Identifier, space, String } + + space { $[ \t\n\r]+ } + + "${[" "]}" + "(" ")" + "=" + "," } @external propSource highlight from "./highlight" + +@detectDelim diff --git a/src-web/components/core/Editor/twig/twig.terms.ts b/src-web/components/core/Editor/twig/twig.terms.ts index d6bda1a33..5011c081f 100644 --- a/src-web/components/core/Editor/twig/twig.terms.ts +++ b/src-web/components/core/Editor/twig/twig.terms.ts @@ -1,8 +1,13 @@ // This file was generated by lezer-generator. You probably shouldn't edit it. export const Template = 1, - Tag = 2, - TagOpen = 3, - TagContent = 4, - TagClose = 5, - Text = 6 + Tag = 4, + Function = 5, + Identifier = 6, + ChainedIdentifier = 7, + FunctionParamList = 10, + Assignment = 11, + String = 13, + Boolean = 14, + Number = 15, + PlainText = 17 diff --git a/src-web/components/core/Editor/twig/twig.ts b/src-web/components/core/Editor/twig/twig.ts index 04452432e..2d16ccf12 100644 --- a/src-web/components/core/Editor/twig/twig.ts +++ b/src-web/components/core/Editor/twig/twig.ts @@ -1,18 +1,22 @@ // This file was generated by lezer-generator. You probably shouldn't edit it. -import {LRParser, LocalTokenGroup} from "@lezer/lr" +import {LRParser} from "@lezer/lr" import {highlight} from "./highlight" export const parser = LRParser.deserialize({ version: 14, - states: "!^QQOPOOOOOO'#C_'#C_OYOQO'#C^OOOO'#Cc'#CcQQOPOOOOOO'#Cd'#CdO_OQO,58xOOOO-E6a-E6aOOOO-E6b-E6bOOOO1G.d1G.d", - stateData: "g~OUROYPO~OSTO~OSTOTXO~O", - goto: "nXPPY^PPPbhTROSTQOSQSORVSQUQRWU", - nodeNames: "⚠ Template Tag TagOpen TagContent TagClose Text", - maxTerm: 10, + states: "$zQVQPOOOsQQO'#C`OOQO'#Cn'#CnQVQPOOO!fQQO'#CtOOQO'#Cw'#CwOzQQO'#CtOOQO'#Ct'#CtOOQO'#Co'#CoO!mQQO,58zOOQO,58z,58zOOQO-E6l-E6lO_QQO,59RO!tQQO'#CfOOQO,58{,58{OOQO-E6m-E6mOOQO1G.f1G.fOOQO1G.m1G.mO#VQSO'#CvOOQO'#Cv'#CvO#bQSO'#CuO#jQQO,59QO#oQSO'#CpO$TQSO,59aOOQO1G.l1G.lO$]QSO'#CtO$kQSO'#CtOOQO,59[,59[OOQO-E6n-E6nO$vQQO,59R", + stateData: "%e~OgOS~ORPOaQO~OUSOVUO]TO^TO_TOlVO~OQYO~P_OX]OQhXUhXVhX]hX^hX_hXlhX~O[[O~PzOQ`O~P_OUbO]TO^TO_TOWiP~O[mOWjX`jX~O`fOWiX~OWhO~OUbO]TO^TO_TOWdX`dX~O`fOWia~OX]O[mOWhX`hX~OX]OWhX`hX~OUiOVjO]TO^TO_TOlVO~Oa^_VUg]V~", + goto: "!|lPPPPmqPPPPw}PPPPPP!X!_!ePPP!k!s!v}TQORXVPX[mX^SUijWVPX[mTc]fQRORZRQXPR_XQgdRlgSWPXTa[mRe]Qd]Rkf", + nodeNames: "⚠ Template ]} ${[ Tag Function Identifier ChainedIdentifier ) ( FunctionParamList Assignment = String Boolean Number , PlainText", + maxTerm: 28, + nodeProps: [ + ["openedBy", 2,"${[",8,"("], + ["closedBy", 3,"]}",9,")"] + ], propSources: [highlight], skippedNodes: [0], - repeatNodeCount: 2, - tokenData: "#]~RTOtbtu!hu;'Sb;'S;=`!]<%lOb~gTU~Otbtuvu;'Sb;'S;=`!]<%lOb~yUO#ob#p;'Sb;'S;=`!]<%l~b~Ob~~!c~!`P;=`<%lb~!hOU~~!kVO#ob#o#p#Q#p;'Sb;'S;=`!]<%l~b~Ob~~!c~#TP!}#O#W~#]OY~", - tokenizers: [1, new LocalTokenGroup("b~RP#P#QU~XP#q#r[~aOT~~", 17, 4)], + repeatNodeCount: 3, + tokenData: "Fe~RzOX#uXY%OYZ%OZ]#u]^%O^p#upq%Oqr#urs%{st#utu+Ouw#uwx+vxy0^yz0tz|#u|}1[}!O1t!O!Q#u!Q!R6h!R![:S![!];_!]!_#u!_!`;u!`!c#u!c!}3Q!}#P#u#P#Q<]#Q#R#u#R#S3Q#S#T#u#T#Y3Q#Y#Z=_#Z#h3Q#h#iCu#i#o3Q#o#p;_#p#q#u#q#r;_#r;'S#u;'S;=`$s<%lO#uP#zTaPOt#utu$Zu;'S#u;'S;=`$s<%lO#uP$^VO!}#u#O#o#u#p;'S#u;'S;=`$s<%l~#u~O#u~~$yP$vP;=`<%l#uP%OOaP~%V[aPg~OX#uXY%OYZ%OZ]#u]^%O^p#upq%Oqt#utu$Zu;'S#u;'S;=`$s<%lO#u~&SXaP]~Or%{rs&ost%{tu'Vu#O%{#O#P)r#P;'S%{;'S;=`*x<%lO%{~&vTaP]~Ot#utu$Zu;'S#u;'S;=`$s<%lO#u~'[[]~Or%{rs&os!}%{!}#O(Q#O#P)r#P#o%{#o#p(Q#p;'S%{;'S;=`*x<%l~%{~O%{~~$y~(VV]~Or(Qrs(ls#O(Q#O#P(q#P;'S(Q;'S;=`)l<%lO(Q~(qO]~~(tRO;'S(Q;'S;=`(};=`O(Q~)SW]~Or(Qrs(ls#O(Q#O#P(q#P;'S(Q;'S;=`)l;=`<%l(Q<%lO(Q~)oP;=`<%l(Q~)wUaPOt%{tu'Vu;'S%{;'S;=`*Z;=`<%l(Q<%lO%{~*`W]~Or(Qrs(ls#O(Q#O#P(q#P;'S(Q;'S;=`)l;=`<%l%{<%lO(Q~*{P;=`<%l%{~+RWO!}#u#O#o#u#o#p+k#p;'S#u;'S;=`$s<%l~#u~O#u~~$y~+nP!}#O+q~+vOR~~+}XaP]~Ot+vtu,juw+vwx&ox#O+v#O#P/Q#P;'S+v;'S;=`0W<%lO+v~,o[]~Ow+vwx&ox!}+v!}#O-e#O#P/Q#P#o+v#o#p-e#p;'S+v;'S;=`0W<%l~+v~O+v~~$y~-jV]~Ow-ewx(lx#O-e#O#P.P#P;'S-e;'S;=`.z<%lO-e~.SRO;'S-e;'S;=`.];=`O-e~.bW]~Ow-ewx(lx#O-e#O#P.P#P;'S-e;'S;=`.z;=`<%l-e<%lO-e~.}P;=`<%l-e~/VUaPOt+vtu,ju;'S+v;'S;=`/i;=`<%l-e<%lO+v~/nW]~Ow-ewx(lx#O-e#O#P.P#P;'S-e;'S;=`.z;=`<%l+v<%lO-e~0ZP;=`<%l+vV0eTXUaPOt#utu$Zu;'S#u;'S;=`$s<%lO#uV0{TWUaPOt#utu$Zu;'S#u;'S;=`$s<%lO#uV1eT`SlQaPOt#utu$Zu;'S#u;'S;=`$s<%lO#u~1{aaPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q!R6h!R![:S![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#o3Q#o;'S#u;'S;=`$s<%lO#u~3X`aPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#o3Q#o;'S#u;'S;=`$s<%lO#u~4`_aPOt#utu$Zu}#u}!O5_!O!Q#u!Q![5_![!c#u!c!}5_!}#R#u#R#S5_#S#T#u#T#o5_#o;'S#u;'S;=`$s<%lO#u~5f`aPV~Ot#utu$Zu}#u}!O5_!O!P4Z!P!Q#u!Q![5_![!c#u!c!}5_!}#R#u#R#S5_#S#T#u#T#o5_#o;'S#u;'S;=`$s<%lO#u~6q`aP_~U~Ot#utu$Zu}#u}!O3Q!O!P7s!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#o3Q#o;'S#u;'S;=`$s<%lO#u~7x_aPOt#utu$Zu}#u}!O5_!O!Q#u!Q![8w![!c#u!c!}5_!}#R#u#R#S5_#S#T#u#T#o5_#o;'S#u;'S;=`$s<%lO#u~9Q`aP_~V~Ot#utu$Zu}#u}!O5_!O!P4Z!P!Q#u!Q![8w![!c#u!c!}5_!}#R#u#R#S5_#S#T#u#T#o5_#o;'S#u;'S;=`$s<%lO#u~:]`aP_~U~Ot#utu$Zu}#u}!O3Q!O!P7s!P!Q#u!Q![:S![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#o3Q#o;'S#u;'S;=`$s<%lO#uR;fTlQaPOt#utu$Zu;'S#u;'S;=`$s<%lO#uV;|T[UaPOt#utu$Zu;'S#u;'S;=`$s<%lO#uRk#U#o3Q#o;'S#u;'S;=`$s<%lO#u~>rbaPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#`3Q#`#a?z#a#o3Q#o;'S#u;'S;=`$s<%lO#u~@RbaPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#g3Q#g#hAZ#h#o3Q#o;'S#u;'S;=`$s<%lO#u~AbbaPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#X3Q#X#YBj#Y#o3Q#o;'S#u;'S;=`$s<%lO#u~Bs`aP^~U~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#o3Q#o;'S#u;'S;=`$s<%lO#u~C|baPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#f3Q#f#gEU#g#o3Q#o;'S#u;'S;=`$s<%lO#u~E]baPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#i3Q#i#jAZ#j#o3Q#o;'S#u;'S;=`$s<%lO#u", + tokenizers: [0, 1, 2], topRules: {"Template":[0,1]}, - tokenPrec: 0 + tokenPrec: 196 }) From 0bcb0928542c018c35dc8f670dd4caa7e283cba9 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 19 May 2025 15:10:56 -0700 Subject: [PATCH 195/996] Update README.md --- README.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a823e290f..d46230a9a 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,11 @@ APIs. It's built using [Tauri](https://tauri.app), Rust, and ReactJS. ![366149288-f18e963f-0b68-4ecb-b8b8-cb71aa9aec02](https://github.com/user-attachments/assets/ca83b7ad-5708-411b-8faf-e36b365841a4) +## Contribution Policy + +Yaak is open source, but only accepting contributions for bug fixes. To get started, +visit [`DEVELOPMENT.md`](DEVELOPMENT.md) for tips on setting up your environment. + ## Feature Overview - 🪂 Import data from Postman, Insomnia, OpenAPI, Swagger, or Curl.
@@ -14,6 +19,7 @@ APIs. It's built using [Tauri](https://tauri.app), Rust, and ReactJS. - ⛓️ Chain together multiple requests to dynamically reference values.
- 📂 Organize requests into workspaces and nested folders.
- 🧮 Use environment variables to easily switch between Prod and Dev.
+- 🛡️ Secure arbitrary text values with end-to-end encryption
- 🏷️ Send dynamic values like UUIDs or timestamps using template tags.
- 🎨 Choose from many of the included themes, or make your own.
- 💽 Mirror workspace data to a directory for integration with Git or Dropbox.
@@ -21,17 +27,8 @@ APIs. It's built using [Tauri](https://tauri.app), Rust, and ReactJS. - 🔌 Create your own plugins for authentication, template tags, and more!
- 🛜 Configure a proxy to access firewall-blocked APIs -## Feedback and Bug Reports - -All feedback, bug reports, questions, and feature requests should be reported to -[feedback.yaak.app](https://feedback.yaak.app). +## Useful Resources -## Community Projects - -- [`yaak2postman`](https://github.com/BiteCraft/yaak2postman) CLI for converting Yaak data - exports to Postman-compatible collections - -## Contribution Policy - -Yaak is open source, but only accepting contributions for bug fixes. To get started, -visit [`DEVELOPMENT.md`](DEVELOPMENT.md) for tips on setting up your environment. +- [Feedback and Bug Reports](https://feedback.yaak.app) +- [Documentation](https://feedback.yaak.app/help) +- [Yaak vs Postman](https://yaak.app/blog/postman-alternative) From 1974d61aa4bee8b7fba604fc9d4d5c6d7e3f3736 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 19 May 2025 15:41:19 -0700 Subject: [PATCH 196/996] Fix syntax highlighting --- src-web/components/core/Editor/twig/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-web/components/core/Editor/twig/extension.ts b/src-web/components/core/Editor/twig/extension.ts index 8e743deb0..ddc187098 100644 --- a/src-web/components/core/Editor/twig/extension.ts +++ b/src-web/components/core/Editor/twig/extension.ts @@ -72,7 +72,7 @@ function mixLanguage(base: LanguageSupport): LRLanguage { return { parser: base.language.parser, - overlay: (node) => node.type.name === 'Text', + overlay: (node) => node.type.name === 'PlainText', }; }), }); From 4c3a02ac53a3ece7d927a4846262c68f9b46473e Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 20 May 2025 07:41:32 -0700 Subject: [PATCH 197/996] Show decrypt error in secure input --- src-web/components/core/Button.tsx | 8 ++- src-web/components/core/Input.tsx | 84 +++++++++++++++++++++++--- src-web/components/core/PlainInput.tsx | 1 + src-web/hooks/useFastMutation.ts | 5 +- 4 files changed, 82 insertions(+), 16 deletions(-) diff --git a/src-web/components/core/Button.tsx b/src-web/components/core/Button.tsx index 35f08e334..e4382d9e5 100644 --- a/src-web/components/core/Button.tsx +++ b/src-web/components/core/Button.tsx @@ -12,7 +12,7 @@ export type ButtonProps = Omit, 'color' | 'onC color?: Color | 'custom' | 'default'; variant?: 'border' | 'solid'; isLoading?: boolean; - size?: '2xs' | 'xs' | 'sm' | 'md'; + size?: '2xs' | 'xs' | 'sm' | 'md' | 'auto'; justify?: 'start' | 'center'; type?: 'button' | 'submit'; forDropdown?: boolean; @@ -114,7 +114,7 @@ export const Button = forwardRef(function Button {...props} > {isLoading ? ( - + ) : leftSlot ? (
{leftSlot}
) : null} @@ -128,7 +128,9 @@ export const Button = forwardRef(function Button {children}
{rightSlot &&
{rightSlot}
} - {forDropdown && } + {forDropdown && ( + + )} ); }); diff --git a/src-web/components/core/Input.tsx b/src-web/components/core/Input.tsx index 5b806eee4..a9cbaedf5 100644 --- a/src-web/components/core/Input.tsx +++ b/src-web/components/core/Input.tsx @@ -11,6 +11,7 @@ import { useRef, useState, } from 'react'; +import { createFastMutation } from '../../hooks/useFastMutation'; import { useIsEncryptionEnabled } from '../../hooks/useIsEncryptionEnabled'; import { useStateWithDeps } from '../../hooks/useStateWithDeps'; import { copyToClipboard } from '../../lib/copy'; @@ -20,7 +21,10 @@ import { convertTemplateToSecure, } from '../../lib/encryption'; import { generateId } from '../../lib/generateId'; -import { withEncryptionEnabled } from '../../lib/setupOrConfigureEncryption'; +import { + setupOrConfigureEncryption, + withEncryptionEnabled, +} from '../../lib/setupOrConfigureEncryption'; import { Button } from './Button'; import type { DropdownItem } from './Dropdown'; import { Dropdown } from './Dropdown'; @@ -29,6 +33,7 @@ import { Editor } from './Editor/Editor'; import type { IconProps } from './Icon'; import { Icon } from './Icon'; import { IconButton } from './IconButton'; +import { IconTooltip } from './IconTooltip'; import { Label } from './Label'; import { HStack } from './Stacks'; @@ -67,7 +72,7 @@ export type InputProps = Pick< placeholder?: string; required?: boolean; rightSlot?: ReactNode; - size?: 'xs' | 'sm' | 'md' | 'auto'; + size?: '2xs' | 'xs' | 'sm' | 'md' | 'auto'; stateKey: EditorProps['stateKey']; tint?: Color; type?: 'text' | 'password'; @@ -169,12 +174,15 @@ const BaseInput = forwardRef(function InputBase( ); const isValid = useMemo(() => { + console.log('CHECKING VALIDITY', validate); if (required && !validateRequire(defaultValue ?? '')) return false; if (typeof validate === 'boolean') return validate; if (typeof validate === 'function' && !validate(defaultValue ?? '')) return false; return true; }, [required, defaultValue, validate]); + console.log('IS VALID', isValid, defaultValue); + const handleChange = useCallback( (value: string) => { onChange?.(value); @@ -231,6 +239,7 @@ const BaseInput = forwardRef(function InputBase( size === 'md' && 'min-h-md', size === 'sm' && 'min-h-sm', size === 'xs' && 'min-h-xs', + size === '2xs' && 'min-h-2xs', )} > {tint != null && ( @@ -332,7 +341,10 @@ function EncryptionInput({ value: string | null; security: ReturnType | null; obscured: boolean; - }>({ fieldType: 'encrypted', value: null, security: null, obscured: true }, [ogForceUpdateKey]); + error: string | null; + }>({ fieldType: 'encrypted', value: null, security: null, obscured: true, error: null }, [ + ogForceUpdateKey, + ]); const forceUpdateKey = `${ogForceUpdateKey}::${state.fieldType}::${state.value === null}`; @@ -345,25 +357,48 @@ function EncryptionInput({ const security = analyzeTemplate(defaultValue ?? ''); if (analyzeTemplate(defaultValue ?? '') === 'global_secured') { // Lazily update value to decrypted representation - convertTemplateToInsecure(defaultValue ?? '').then((value) => { - setState({ fieldType: 'encrypted', security, value, obscured: true }); + templateToInsecure.mutate(defaultValue ?? '', { + onSuccess: (value) => { + setState({ fieldType: 'encrypted', security, value, obscured: true, error: null }); + }, + onError: (value) => { + setState({ + fieldType: 'encrypted', + security, + value: null, + error: String(value), + obscured: true, + }); + }, }); } else if (isEncryptionEnabled && !defaultValue) { // Default to encrypted field for new encrypted inputs - setState({ fieldType: 'encrypted', security, value: '', obscured: true }); + setState({ fieldType: 'encrypted', security, value: '', obscured: true, error: null }); } else if (isEncryptionEnabled) { // Don't obscure plain text when encryption is enabled - setState({ fieldType: 'text', security, value: defaultValue ?? '', obscured: false }); + setState({ + fieldType: 'text', + security, + value: defaultValue ?? '', + obscured: false, + error: null, + }); } else { // Don't obscure plain text when encryption is disabled - setState({ fieldType: 'text', security, value: defaultValue ?? '', obscured: true }); + setState({ + fieldType: 'text', + security, + value: defaultValue ?? '', + obscured: true, + error: null, + }); } }, [defaultValue, isEncryptionEnabled, setState, state.value]); const handleChange = useCallback( (value: string, fieldType: PasswordFieldType) => { if (fieldType === 'encrypted') { - convertTemplateToSecure(value).then((value) => onChange?.(value)); + templateToSecure.mutate(value, { onSuccess: (value) => onChange?.(value) }); } else { onChange?.(value); } @@ -372,7 +407,7 @@ function EncryptionInput({ const security = fieldType === 'encrypted' ? 'global_secured' : analyzeTemplate(value); // Reset obscured value when the field type is being changed const obscured = fieldType === s.fieldType ? s.obscured : fieldType !== 'text'; - return { fieldType, value, security, obscured }; + return { fieldType, value, security, obscured, error: s.error }; }); }, [onChange, setState], @@ -477,6 +512,23 @@ function EncryptionInput({ const type = state.obscured ? 'password' : 'text'; + if (state.error) { + return ( + + ); + } + return ( ); } + +const templateToSecure = createFastMutation({ + mutationKey: ['template-to-secure'], + mutationFn: convertTemplateToSecure, +}); + +const templateToInsecure = createFastMutation({ + mutationKey: ['template-to-insecure'], + mutationFn: convertTemplateToInsecure, + disableToastError: true, +}); diff --git a/src-web/components/core/PlainInput.tsx b/src-web/components/core/PlainInput.tsx index 1d18a44e4..c4ad205c2 100644 --- a/src-web/components/core/PlainInput.tsx +++ b/src-web/components/core/PlainInput.tsx @@ -116,6 +116,7 @@ export function PlainInput({ size === 'md' && 'min-h-md', size === 'sm' && 'min-h-sm', size === 'xs' && 'min-h-xs', + size === '2xs' && 'min-h-2xs', )} > {tint != null && ( diff --git a/src-web/hooks/useFastMutation.ts b/src-web/hooks/useFastMutation.ts index 194c8eeef..81b1c28ee 100644 --- a/src-web/hooks/useFastMutation.ts +++ b/src-web/hooks/useFastMutation.ts @@ -30,6 +30,7 @@ export function createFastMutation Date: Tue, 20 May 2025 08:08:56 -0700 Subject: [PATCH 198/996] Fix Insomnia v5 importer --- plugins/importer-insomnia/src/v5.ts | 4 +- .../tests/fixtures/basic.output.json | 1 + .../fixtures/version-5-minimal.input.yaml | 72 +++++++++++++++ .../fixtures/version-5-minimal.output.json | 87 +++++++++++++++++++ 4 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 plugins/importer-insomnia/tests/fixtures/version-5-minimal.input.yaml create mode 100644 plugins/importer-insomnia/tests/fixtures/version-5-minimal.output.json diff --git a/plugins/importer-insomnia/src/v5.ts b/plugins/importer-insomnia/src/v5.ts index f85b9010f..523d5abe8 100644 --- a/plugins/importer-insomnia/src/v5.ts +++ b/plugins/importer-insomnia/src/v5.ts @@ -75,7 +75,7 @@ function importHttpRequest( let bodyType: string | null = null; let body = {}; - if (r.body.mimeType === 'application/octet-stream') { + if (r.body?.mimeType === 'application/octet-stream') { bodyType = 'binary'; body = { filePath: r.body.fileName ?? '' }; } else if (r.body?.mimeType === 'application/x-www-form-urlencoded') { @@ -256,7 +256,7 @@ function importEnvironment(e: any, workspaceId: string, isParent?: boolean): Par base: isParent ?? e.parentId === workspaceId, model: 'environment', name: e.name, - variables: Object.entries(e.data).map(([name, value]) => ({ + variables: Object.entries(e.data ?? {}).map(([name, value]) => ({ enabled: true, name, value: `${value}`, diff --git a/plugins/importer-insomnia/tests/fixtures/basic.output.json b/plugins/importer-insomnia/tests/fixtures/basic.output.json index f640dc7cb..235a227db 100644 --- a/plugins/importer-insomnia/tests/fixtures/basic.output.json +++ b/plugins/importer-insomnia/tests/fixtures/basic.output.json @@ -113,6 +113,7 @@ "workspaceId": "GENERATE_ID::wrk_d4d92f7c0ee947b89159243506687019" } ], + "websocketRequests": [], "workspaces": [ { "createdAt": "2025-01-13T15:15:43.765", diff --git a/plugins/importer-insomnia/tests/fixtures/version-5-minimal.input.yaml b/plugins/importer-insomnia/tests/fixtures/version-5-minimal.input.yaml new file mode 100644 index 000000000..ff7a005bf --- /dev/null +++ b/plugins/importer-insomnia/tests/fixtures/version-5-minimal.input.yaml @@ -0,0 +1,72 @@ +type: collection.insomnia.rest/5.0 +name: Debugging +meta: + id: wrk_9717dd1c9e0c4b2e9ed6d2abcf3bd45c + created: 1747197924902 + modified: 1747197924902 +collection: + - name: My Folder + meta: + id: fld_296933ea4ea84783a775d199997e9be7 + created: 1747414092298 + modified: 1747414142427 + sortKey: -1747414092298 + children: + - url: https://httpbin.org/post + name: New Request + meta: + id: req_9a80320365ac4509ade406359dbc6a71 + created: 1747197928502 + modified: 1747414129313 + isPrivate: false + sortKey: -1747414129276 + method: GET + headers: + - name: User-Agent + value: insomnia/11.1.0 + id: pair_6ae87d1620a9494f8e5b29cd9f92d087 + settings: + renderRequestBody: true + encodeUrl: true + followRedirects: global + cookies: + send: true + store: true + rebuildPath: true + headers: + - id: pair_f2b330e3914f4c11b209318aef94325c + name: foo + value: bar + disabled: false + - name: New Request + meta: + id: req_e3f8cdbd58784a539dd4c1e127d73451 + created: 1747414160497 + modified: 1747414160497 + isPrivate: false + sortKey: -1747414160498 + method: GET + headers: + - name: User-Agent + value: insomnia/11.1.0 + settings: + renderRequestBody: true + encodeUrl: true + followRedirects: global + cookies: + send: true + store: true + rebuildPath: true +cookieJar: + name: Default Jar + meta: + id: jar_e46dc73e8ccda30ca132153e8f11183bd08119ce + created: 1747197924904 + modified: 1747197924904 +environments: + name: Base Environment + meta: + id: env_e46dc73e8ccda30ca132153e8f11183bd08119ce + created: 1747197924903 + modified: 1747197924903 + isPrivate: false diff --git a/plugins/importer-insomnia/tests/fixtures/version-5-minimal.output.json b/plugins/importer-insomnia/tests/fixtures/version-5-minimal.output.json new file mode 100644 index 000000000..b581956ca --- /dev/null +++ b/plugins/importer-insomnia/tests/fixtures/version-5-minimal.output.json @@ -0,0 +1,87 @@ +{ + "resources": { + "environments": [ + { + "base": true, + "createdAt": "2025-05-14T04:45:24.903", + "id": "GENERATE_ID::env_e46dc73e8ccda30ca132153e8f11183bd08119ce", + "model": "environment", + "name": "Base Environment", + "public": true, + "updatedAt": "2025-05-14T04:45:24.903", + "variables": [], + "workspaceId": "GENERATE_ID::wrk_9717dd1c9e0c4b2e9ed6d2abcf3bd45c" + } + ], + "folders": [ + { + "createdAt": "2025-05-16T16:48:12.298", + "folderId": null, + "id": "GENERATE_ID::fld_296933ea4ea84783a775d199997e9be7", + "model": "folder", + "name": "My Folder", + "sortPriority": -1747414092298, + "updatedAt": "2025-05-16T16:49:02.427", + "workspaceId": "GENERATE_ID::wrk_9717dd1c9e0c4b2e9ed6d2abcf3bd45c" + } + ], + "grpcRequests": [], + "httpRequests": [ + { + "authentication": {}, + "authenticationType": null, + "body": {}, + "bodyType": null, + "createdAt": "2025-05-14T04:45:28.502", + "folderId": "GENERATE_ID::fld_296933ea4ea84783a775d199997e9be7", + "headers": [ + { + "enabled": true, + "name": "User-Agent", + "value": "insomnia/11.1.0" + } + ], + "id": "GENERATE_ID::req_9a80320365ac4509ade406359dbc6a71", + "method": "GET", + "model": "http_request", + "name": "New Request", + "sortPriority": -1747414129276, + "updatedAt": "2025-05-16T16:48:49.313", + "url": "https://httpbin.org/post", + "workspaceId": "GENERATE_ID::wrk_9717dd1c9e0c4b2e9ed6d2abcf3bd45c" + }, + { + "authentication": {}, + "authenticationType": null, + "body": {}, + "bodyType": null, + "createdAt": "2025-05-16T16:49:20.497", + "folderId": null, + "headers": [ + { + "enabled": true, + "name": "User-Agent", + "value": "insomnia/11.1.0" + } + ], + "id": "GENERATE_ID::req_e3f8cdbd58784a539dd4c1e127d73451", + "method": "GET", + "model": "http_request", + "name": "New Request", + "sortPriority": -1747414160498, + "updatedAt": "2025-05-16T16:49:20.497", + "workspaceId": "GENERATE_ID::wrk_9717dd1c9e0c4b2e9ed6d2abcf3bd45c" + } + ], + "websocketRequests": [], + "workspaces": [ + { + "createdAt": "2025-05-14T04:45:24.902", + "id": "GENERATE_ID::wrk_9717dd1c9e0c4b2e9ed6d2abcf3bd45c", + "model": "workspace", + "name": "Debugging", + "updatedAt": "2025-05-14T04:45:24.902" + } + ] + } +} From bc3a5e3e582298a0b052a0932a8552b2413250c3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 20 May 2025 08:13:57 -0700 Subject: [PATCH 199/996] Include license status in notification endpoint --- src-tauri/src/notifications.rs | 11 ++++++ src-tauri/yaak-license/src/commands.rs | 48 +++----------------------- src-tauri/yaak-license/src/lib.rs | 12 +++++++ src-tauri/yaak-license/src/license.rs | 37 +++++++++++--------- 4 files changed, 48 insertions(+), 60 deletions(-) diff --git a/src-tauri/src/notifications.rs b/src-tauri/src/notifications.rs index 71e4be471..3eaf30d59 100644 --- a/src-tauri/src/notifications.rs +++ b/src-tauri/src/notifications.rs @@ -1,3 +1,4 @@ +use std::ops::Deref; use std::time::SystemTime; use crate::error::Result; @@ -8,6 +9,7 @@ use reqwest::Method; use serde::{Deserialize, Serialize}; use serde_json::Value; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow}; +use yaak_license::{check_license, LicenseCheckStatus}; use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::UpdateSource; @@ -70,6 +72,13 @@ impl YaakNotifier { self.last_check = SystemTime::now(); + let license_check = match check_license(window).await? { + LicenseCheckStatus::PersonalUse { .. } => "personal".to_string(), + LicenseCheckStatus::CommercialUse => "commercial".to_string(), + LicenseCheckStatus::InvalidLicense => "invalid_license".to_string(), + LicenseCheckStatus::Trialing { .. } => "trialing".to_string(), + }; + let settings = window.db().get_settings(); let num_launches = get_num_launches(app_handle).await; let info = app_handle.package_info().clone(); let req = reqwest::Client::default() @@ -77,6 +86,8 @@ impl YaakNotifier { .query(&[ ("version", info.version.to_string().as_str()), ("launches", num_launches.to_string().as_str()), + ("installed", settings.created_at.format("%Y-%m-%d").to_string().as_str()), + ("license", &license_check), ("platform", get_os()), ]); let resp = req.send().await?; diff --git a/src-tauri/yaak-license/src/commands.rs b/src-tauri/yaak-license/src/commands.rs index ced67c969..476d39e7d 100644 --- a/src-tauri/yaak-license/src/commands.rs +++ b/src-tauri/yaak-license/src/commands.rs @@ -1,60 +1,22 @@ use crate::error::Result; -use crate::{ - activate_license, check_license, deactivate_license, ActivateLicenseRequestPayload, - CheckActivationRequestPayload, DeactivateLicenseRequestPayload, LicenseCheckStatus, -}; +use crate::{LicenseCheckStatus, activate_license, check_license, deactivate_license}; use log::{debug, info}; -use std::string::ToString; -use tauri::{command, Manager, Runtime, WebviewWindow}; +use tauri::{Runtime, WebviewWindow, command}; #[command] pub async fn check(window: WebviewWindow) -> Result { debug!("Checking license"); - check_license( - &window, - CheckActivationRequestPayload { - app_platform: get_os().to_string(), - app_version: window.package_info().version.to_string(), - }, - ) - .await + check_license(&window).await } #[command] pub async fn activate(license_key: &str, window: WebviewWindow) -> Result<()> { info!("Activating license {}", license_key); - activate_license( - &window, - ActivateLicenseRequestPayload { - license_key: license_key.to_string(), - app_platform: get_os().to_string(), - app_version: window.app_handle().package_info().version.to_string(), - }, - ) - .await + activate_license(&window, license_key).await } #[command] pub async fn deactivate(window: WebviewWindow) -> Result<()> { info!("Deactivating activation"); - deactivate_license( - &window, - DeactivateLicenseRequestPayload { - app_platform: get_os().to_string(), - app_version: window.app_handle().package_info().version.to_string(), - }, - ) - .await -} - -fn get_os() -> &'static str { - if cfg!(target_os = "windows") { - "windows" - } else if cfg!(target_os = "macos") { - "macos" - } else if cfg!(target_os = "linux") { - "linux" - } else { - "unknown" - } + deactivate_license(&window).await } diff --git a/src-tauri/yaak-license/src/lib.rs b/src-tauri/yaak-license/src/lib.rs index 03b76bfcd..dd8fd540c 100644 --- a/src-tauri/yaak-license/src/lib.rs +++ b/src-tauri/yaak-license/src/lib.rs @@ -16,3 +16,15 @@ pub fn init() -> TauriPlugin { .invoke_handler(generate_handler![check, activate, deactivate]) .build() } + +pub(crate) fn get_os() -> &'static str { + if cfg!(target_os = "windows") { + "windows" + } else if cfg!(target_os = "macos") { + "macos" + } else if cfg!(target_os = "linux") { + "linux" + } else { + "unknown" + } +} diff --git a/src-tauri/yaak-license/src/license.rs b/src-tauri/yaak-license/src/license.rs index e36caa079..9e22f8581 100644 --- a/src-tauri/yaak-license/src/license.rs +++ b/src-tauri/yaak-license/src/license.rs @@ -5,7 +5,7 @@ use log::{debug, info, warn}; use serde::{Deserialize, Serialize}; use std::ops::Add; use std::time::Duration; -use tauri::{is_dev, AppHandle, Emitter, Manager, Runtime, WebviewWindow}; +use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow, is_dev}; use ts_rs::TS; use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::UpdateSource; @@ -63,10 +63,15 @@ pub struct APIErrorResponsePayload { pub async fn activate_license( window: &WebviewWindow, - p: ActivateLicenseRequestPayload, + license_key: &str, ) -> Result<()> { let client = reqwest::Client::new(); - let response = client.post(build_url("/licenses/activate")).json(&p).send().await?; + let payload = ActivateLicenseRequestPayload { + license_key: license_key.to_string(), + app_platform: crate::get_os().to_string(), + app_version: window.app_handle().package_info().version.to_string(), + }; + let response = client.post(build_url("/licenses/activate")).json(&payload).send().await?; if response.status().is_client_error() { let body: APIErrorResponsePayload = response.json().await?; @@ -95,16 +100,17 @@ pub async fn activate_license( Ok(()) } -pub async fn deactivate_license( - window: &WebviewWindow, - p: DeactivateLicenseRequestPayload, -) -> Result<()> { +pub async fn deactivate_license(window: &WebviewWindow) -> Result<()> { let app_handle = window.app_handle(); let activation_id = get_activation_id(app_handle).await; let client = reqwest::Client::new(); let path = format!("/licenses/activations/{}/deactivate", activation_id); - let response = client.post(build_url(&path)).json(&p).send().await?; + let payload = DeactivateLicenseRequestPayload { + app_platform: crate::get_os().to_string(), + app_version: window.app_handle().package_info().version.to_string(), + }; + let response = client.post(build_url(&path)).json(&payload).send().await?; if response.status().is_client_error() { let body: APIErrorResponsePayload = response.json().await?; @@ -141,10 +147,11 @@ pub enum LicenseCheckStatus { Trialing { end: NaiveDateTime }, } -pub async fn check_license( - window: &WebviewWindow, - payload: CheckActivationRequestPayload, -) -> Result { +pub async fn check_license(window: &WebviewWindow) -> Result { + let payload = CheckActivationRequestPayload { + app_platform: crate::get_os().to_string(), + app_version: window.package_info().version.to_string(), + }; let activation_id = get_activation_id(window.app_handle()).await; let settings = window.db().get_settings(); let trial_end = settings.created_at.add(Duration::from_secs(TRIAL_SECONDS)); @@ -197,9 +204,5 @@ fn build_url(path: &str) -> String { } pub async fn get_activation_id(app_handle: &AppHandle) -> String { - app_handle.db().get_key_value_string( - KV_ACTIVATION_ID_KEY, - KV_NAMESPACE, - "", - ) + app_handle.db().get_key_value_string(KV_ACTIVATION_ID_KEY, KV_NAMESPACE, "") } From a4c600cb4861dd42ba3fe907a076ff0cd88c0cbb Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 20 May 2025 08:15:19 -0700 Subject: [PATCH 200/996] Lint errors --- src-tauri/src/notifications.rs | 3 +-- src-web/components/SelectFile.tsx | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src-tauri/src/notifications.rs b/src-tauri/src/notifications.rs index 3eaf30d59..29fa1bc65 100644 --- a/src-tauri/src/notifications.rs +++ b/src-tauri/src/notifications.rs @@ -1,4 +1,3 @@ -use std::ops::Deref; use std::time::SystemTime; use crate::error::Result; @@ -9,7 +8,7 @@ use reqwest::Method; use serde::{Deserialize, Serialize}; use serde_json::Value; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow}; -use yaak_license::{check_license, LicenseCheckStatus}; +use yaak_license::{LicenseCheckStatus, check_license}; use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::UpdateSource; diff --git a/src-web/components/SelectFile.tsx b/src-web/components/SelectFile.tsx index 3cbfb998a..cbde24665 100644 --- a/src-web/components/SelectFile.tsx +++ b/src-web/components/SelectFile.tsx @@ -80,7 +80,7 @@ export function SelectFile({ <> {filePath && ( Date: Wed, 21 May 2025 08:18:09 -0700 Subject: [PATCH 201/996] Fix template parsing --- .../components/core/Editor/twig/highlight.ts | 13 +--- .../core/Editor/twig/templateTags.ts | 4 ++ .../components/core/Editor/twig/twig.grammar | 69 +++---------------- .../components/core/Editor/twig/twig.terms.ts | 15 ++-- src-web/components/core/Editor/twig/twig.ts | 24 +++---- 5 files changed, 30 insertions(+), 95 deletions(-) diff --git a/src-web/components/core/Editor/twig/highlight.ts b/src-web/components/core/Editor/twig/highlight.ts index e33381eaf..b91d6ed9d 100644 --- a/src-web/components/core/Editor/twig/highlight.ts +++ b/src-web/components/core/Editor/twig/highlight.ts @@ -1,14 +1,7 @@ import { styleTags, tags as t } from '@lezer/highlight'; export const highlight = styleTags({ - "${[": t.bracket, - "]}": t.bracket, - "(": t.bracket, - ")": t.bracket, - "=": t.bracket, - ",": t.bracket, - Tag: t.keyword, - Identifier: t.variableName, - ChainedIdentifier: t.variableName, - Boolean: t.bool, + TagOpen: t.bracket, + TagClose: t.bracket, + TagContent: t.keyword, }); diff --git a/src-web/components/core/Editor/twig/templateTags.ts b/src-web/components/core/Editor/twig/templateTags.ts index e34fe5bd0..79d37dcf2 100644 --- a/src-web/components/core/Editor/twig/templateTags.ts +++ b/src-web/components/core/Editor/twig/templateTags.ts @@ -80,6 +80,10 @@ function templateTags( const inner = rawTag.replace(/^\$\{\[\s*/, '').replace(/\s*]}$/, ''); let name = inner.match(/([\w.]+)[(]/)?.[1] ?? inner; + if (inner.includes('\n')) { + return; + } + // The beta named the function `Response` but was changed in stable. // Keep this here for a while because there's no easy way to migrate if (name === 'Response') { diff --git a/src-web/components/core/Editor/twig/twig.grammar b/src-web/components/core/Editor/twig/twig.grammar index 6d31100db..5706e2003 100644 --- a/src-web/components/core/Editor/twig/twig.grammar +++ b/src-web/components/core/Editor/twig/twig.grammar @@ -1,70 +1,17 @@ -@precedence { - top, - mid, - lesser -} - -@top Template { (Tag | PlainText)* } - -@skip { space } - -Tag { "${[" expression* "]}" } - -commaSep { "" | content ("," content?)* } - -expression { - Function | - Assignment | - Identifier | - ChainedIdentifier | - basicType | - hashStructure -} - -basicType { - String | - Boolean | - Number -} +@top Template { (Tag | Text)* } -functionParam { - Identifier | - Assignment | - basicType +@local tokens { + TagClose { "]}" } + @else TagContent } -FunctionParamList { - "(" commaSep ")" +@skip { } { + TagOpen { "${[" } + Tag { TagOpen (TagContent)+ TagClose } } -Assignment { Identifier "=" expression } - -Function { (Identifier | ChainedIdentifier) !top FunctionParamList} - @tokens { - PlainText { ![$] PlainText? | "$" (@eof | ![{[] PlainText?) } - - Identifier { $[a-zA-Z_\-0-9]+ } - ChainedIdentifier { Identifier ("." Identifier)+ } - - hashStructure { "{" | "}" | ":" | ","} - - Boolean { "true" | "false" } - String { ("'" (![\\'] | "\\" _)* "'"?) | ("\"" (![\\"] | "\\" _)* "\""?) } - Number { '-'? int frac? } - int { '0' | $[1-9] @digit* } - frac { '.' @digit+ } - - @precedence { PlainText, Boolean, Number, ChainedIdentifier, Identifier, space, String } - - space { $[ \t\n\r]+ } - - "${[" "]}" - "(" ")" - "=" - "," + Text { ![$] Text? | "$" (@eof | ![{] Text?) } } @external propSource highlight from "./highlight" - -@detectDelim diff --git a/src-web/components/core/Editor/twig/twig.terms.ts b/src-web/components/core/Editor/twig/twig.terms.ts index 5011c081f..d6bda1a33 100644 --- a/src-web/components/core/Editor/twig/twig.terms.ts +++ b/src-web/components/core/Editor/twig/twig.terms.ts @@ -1,13 +1,8 @@ // This file was generated by lezer-generator. You probably shouldn't edit it. export const Template = 1, - Tag = 4, - Function = 5, - Identifier = 6, - ChainedIdentifier = 7, - FunctionParamList = 10, - Assignment = 11, - String = 13, - Boolean = 14, - Number = 15, - PlainText = 17 + Tag = 2, + TagOpen = 3, + TagContent = 4, + TagClose = 5, + Text = 6 diff --git a/src-web/components/core/Editor/twig/twig.ts b/src-web/components/core/Editor/twig/twig.ts index 2d16ccf12..04452432e 100644 --- a/src-web/components/core/Editor/twig/twig.ts +++ b/src-web/components/core/Editor/twig/twig.ts @@ -1,22 +1,18 @@ // This file was generated by lezer-generator. You probably shouldn't edit it. -import {LRParser} from "@lezer/lr" +import {LRParser, LocalTokenGroup} from "@lezer/lr" import {highlight} from "./highlight" export const parser = LRParser.deserialize({ version: 14, - states: "$zQVQPOOOsQQO'#C`OOQO'#Cn'#CnQVQPOOO!fQQO'#CtOOQO'#Cw'#CwOzQQO'#CtOOQO'#Ct'#CtOOQO'#Co'#CoO!mQQO,58zOOQO,58z,58zOOQO-E6l-E6lO_QQO,59RO!tQQO'#CfOOQO,58{,58{OOQO-E6m-E6mOOQO1G.f1G.fOOQO1G.m1G.mO#VQSO'#CvOOQO'#Cv'#CvO#bQSO'#CuO#jQQO,59QO#oQSO'#CpO$TQSO,59aOOQO1G.l1G.lO$]QSO'#CtO$kQSO'#CtOOQO,59[,59[OOQO-E6n-E6nO$vQQO,59R", - stateData: "%e~OgOS~ORPOaQO~OUSOVUO]TO^TO_TOlVO~OQYO~P_OX]OQhXUhXVhX]hX^hX_hXlhX~O[[O~PzOQ`O~P_OUbO]TO^TO_TOWiP~O[mOWjX`jX~O`fOWiX~OWhO~OUbO]TO^TO_TOWdX`dX~O`fOWia~OX]O[mOWhX`hX~OX]OWhX`hX~OUiOVjO]TO^TO_TOlVO~Oa^_VUg]V~", - goto: "!|lPPPPmqPPPPw}PPPPPP!X!_!ePPP!k!s!v}TQORXVPX[mX^SUijWVPX[mTc]fQRORZRQXPR_XQgdRlgSWPXTa[mRe]Qd]Rkf", - nodeNames: "⚠ Template ]} ${[ Tag Function Identifier ChainedIdentifier ) ( FunctionParamList Assignment = String Boolean Number , PlainText", - maxTerm: 28, - nodeProps: [ - ["openedBy", 2,"${[",8,"("], - ["closedBy", 3,"]}",9,")"] - ], + states: "!^QQOPOOOOOO'#C_'#C_OYOQO'#C^OOOO'#Cc'#CcQQOPOOOOOO'#Cd'#CdO_OQO,58xOOOO-E6a-E6aOOOO-E6b-E6bOOOO1G.d1G.d", + stateData: "g~OUROYPO~OSTO~OSTOTXO~O", + goto: "nXPPY^PPPbhTROSTQOSQSORVSQUQRWU", + nodeNames: "⚠ Template Tag TagOpen TagContent TagClose Text", + maxTerm: 10, propSources: [highlight], skippedNodes: [0], - repeatNodeCount: 3, - tokenData: "Fe~RzOX#uXY%OYZ%OZ]#u]^%O^p#upq%Oqr#urs%{st#utu+Ouw#uwx+vxy0^yz0tz|#u|}1[}!O1t!O!Q#u!Q!R6h!R![:S![!];_!]!_#u!_!`;u!`!c#u!c!}3Q!}#P#u#P#Q<]#Q#R#u#R#S3Q#S#T#u#T#Y3Q#Y#Z=_#Z#h3Q#h#iCu#i#o3Q#o#p;_#p#q#u#q#r;_#r;'S#u;'S;=`$s<%lO#uP#zTaPOt#utu$Zu;'S#u;'S;=`$s<%lO#uP$^VO!}#u#O#o#u#p;'S#u;'S;=`$s<%l~#u~O#u~~$yP$vP;=`<%l#uP%OOaP~%V[aPg~OX#uXY%OYZ%OZ]#u]^%O^p#upq%Oqt#utu$Zu;'S#u;'S;=`$s<%lO#u~&SXaP]~Or%{rs&ost%{tu'Vu#O%{#O#P)r#P;'S%{;'S;=`*x<%lO%{~&vTaP]~Ot#utu$Zu;'S#u;'S;=`$s<%lO#u~'[[]~Or%{rs&os!}%{!}#O(Q#O#P)r#P#o%{#o#p(Q#p;'S%{;'S;=`*x<%l~%{~O%{~~$y~(VV]~Or(Qrs(ls#O(Q#O#P(q#P;'S(Q;'S;=`)l<%lO(Q~(qO]~~(tRO;'S(Q;'S;=`(};=`O(Q~)SW]~Or(Qrs(ls#O(Q#O#P(q#P;'S(Q;'S;=`)l;=`<%l(Q<%lO(Q~)oP;=`<%l(Q~)wUaPOt%{tu'Vu;'S%{;'S;=`*Z;=`<%l(Q<%lO%{~*`W]~Or(Qrs(ls#O(Q#O#P(q#P;'S(Q;'S;=`)l;=`<%l%{<%lO(Q~*{P;=`<%l%{~+RWO!}#u#O#o#u#o#p+k#p;'S#u;'S;=`$s<%l~#u~O#u~~$y~+nP!}#O+q~+vOR~~+}XaP]~Ot+vtu,juw+vwx&ox#O+v#O#P/Q#P;'S+v;'S;=`0W<%lO+v~,o[]~Ow+vwx&ox!}+v!}#O-e#O#P/Q#P#o+v#o#p-e#p;'S+v;'S;=`0W<%l~+v~O+v~~$y~-jV]~Ow-ewx(lx#O-e#O#P.P#P;'S-e;'S;=`.z<%lO-e~.SRO;'S-e;'S;=`.];=`O-e~.bW]~Ow-ewx(lx#O-e#O#P.P#P;'S-e;'S;=`.z;=`<%l-e<%lO-e~.}P;=`<%l-e~/VUaPOt+vtu,ju;'S+v;'S;=`/i;=`<%l-e<%lO+v~/nW]~Ow-ewx(lx#O-e#O#P.P#P;'S-e;'S;=`.z;=`<%l+v<%lO-e~0ZP;=`<%l+vV0eTXUaPOt#utu$Zu;'S#u;'S;=`$s<%lO#uV0{TWUaPOt#utu$Zu;'S#u;'S;=`$s<%lO#uV1eT`SlQaPOt#utu$Zu;'S#u;'S;=`$s<%lO#u~1{aaPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q!R6h!R![:S![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#o3Q#o;'S#u;'S;=`$s<%lO#u~3X`aPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#o3Q#o;'S#u;'S;=`$s<%lO#u~4`_aPOt#utu$Zu}#u}!O5_!O!Q#u!Q![5_![!c#u!c!}5_!}#R#u#R#S5_#S#T#u#T#o5_#o;'S#u;'S;=`$s<%lO#u~5f`aPV~Ot#utu$Zu}#u}!O5_!O!P4Z!P!Q#u!Q![5_![!c#u!c!}5_!}#R#u#R#S5_#S#T#u#T#o5_#o;'S#u;'S;=`$s<%lO#u~6q`aP_~U~Ot#utu$Zu}#u}!O3Q!O!P7s!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#o3Q#o;'S#u;'S;=`$s<%lO#u~7x_aPOt#utu$Zu}#u}!O5_!O!Q#u!Q![8w![!c#u!c!}5_!}#R#u#R#S5_#S#T#u#T#o5_#o;'S#u;'S;=`$s<%lO#u~9Q`aP_~V~Ot#utu$Zu}#u}!O5_!O!P4Z!P!Q#u!Q![8w![!c#u!c!}5_!}#R#u#R#S5_#S#T#u#T#o5_#o;'S#u;'S;=`$s<%lO#u~:]`aP_~U~Ot#utu$Zu}#u}!O3Q!O!P7s!P!Q#u!Q![:S![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#o3Q#o;'S#u;'S;=`$s<%lO#uR;fTlQaPOt#utu$Zu;'S#u;'S;=`$s<%lO#uV;|T[UaPOt#utu$Zu;'S#u;'S;=`$s<%lO#uRk#U#o3Q#o;'S#u;'S;=`$s<%lO#u~>rbaPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#`3Q#`#a?z#a#o3Q#o;'S#u;'S;=`$s<%lO#u~@RbaPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#g3Q#g#hAZ#h#o3Q#o;'S#u;'S;=`$s<%lO#u~AbbaPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#X3Q#X#YBj#Y#o3Q#o;'S#u;'S;=`$s<%lO#u~Bs`aP^~U~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#o3Q#o;'S#u;'S;=`$s<%lO#u~C|baPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#f3Q#f#gEU#g#o3Q#o;'S#u;'S;=`$s<%lO#u~E]baPU~Ot#utu$Zu}#u}!O3Q!O!P4Z!P!Q#u!Q![3Q![!c#u!c!}3Q!}#R#u#R#S3Q#S#T#u#T#i3Q#i#jAZ#j#o3Q#o;'S#u;'S;=`$s<%lO#u", - tokenizers: [0, 1, 2], + repeatNodeCount: 2, + tokenData: "#]~RTOtbtu!hu;'Sb;'S;=`!]<%lOb~gTU~Otbtuvu;'Sb;'S;=`!]<%lOb~yUO#ob#p;'Sb;'S;=`!]<%l~b~Ob~~!c~!`P;=`<%lb~!hOU~~!kVO#ob#o#p#Q#p;'Sb;'S;=`!]<%l~b~Ob~~!c~#TP!}#O#W~#]OY~", + tokenizers: [1, new LocalTokenGroup("b~RP#P#QU~XP#q#r[~aOT~~", 17, 4)], topRules: {"Template":[0,1]}, - tokenPrec: 196 + tokenPrec: 0 }) From d8b1cadae620bae3f30563e538be3adbc71d71d7 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 21 May 2025 08:25:12 -0700 Subject: [PATCH 202/996] Fix model deletion --- src-web/components/core/Input.tsx | 3 --- src-web/components/sidebar/SidebarItemContextMenu.tsx | 11 ++++------- src-web/lib/deleteModelWithConfirm.tsx | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src-web/components/core/Input.tsx b/src-web/components/core/Input.tsx index a9cbaedf5..65f1e7447 100644 --- a/src-web/components/core/Input.tsx +++ b/src-web/components/core/Input.tsx @@ -174,15 +174,12 @@ const BaseInput = forwardRef(function InputBase( ); const isValid = useMemo(() => { - console.log('CHECKING VALIDITY', validate); if (required && !validateRequire(defaultValue ?? '')) return false; if (typeof validate === 'boolean') return validate; if (typeof validate === 'function' && !validate(defaultValue ?? '')) return false; return true; }, [required, defaultValue, validate]); - console.log('IS VALID', isValid, defaultValue); - const handleChange = useCallback( (value: string) => { onChange?.(value); diff --git a/src-web/components/sidebar/SidebarItemContextMenu.tsx b/src-web/components/sidebar/SidebarItemContextMenu.tsx index 0b3fd5f5f..6a79a22ab 100644 --- a/src-web/components/sidebar/SidebarItemContextMenu.tsx +++ b/src-web/components/sidebar/SidebarItemContextMenu.tsx @@ -1,9 +1,4 @@ -import { - deleteModelById, - duplicateModelById, - getModel, - workspacesAtom, -} from '@yaakapp-internal/models'; +import { duplicateModelById, getModel, workspacesAtom } from '@yaakapp-internal/models'; import { useAtomValue } from 'jotai'; import React, { useMemo } from 'react'; import { useCreateDropdownItems } from '../../hooks/useCreateDropdownItems'; @@ -134,7 +129,9 @@ export function SidebarItemContextMenu({ child, show, close }: Props) { hotKeyAction: 'sidebar.delete_selected_item', hotKeyLabelOnly: true, leftSlot: , - onSelect: async () => deleteModelById(child.model, child.id), + onSelect: async () => { + await deleteModelWithConfirm(getModel(child.model, child.id)); + }, }, ]; } diff --git a/src-web/lib/deleteModelWithConfirm.tsx b/src-web/lib/deleteModelWithConfirm.tsx index f92bdac4d..ff42409c0 100644 --- a/src-web/lib/deleteModelWithConfirm.tsx +++ b/src-web/lib/deleteModelWithConfirm.tsx @@ -11,7 +11,7 @@ export async function deleteModelWithConfirm(model: AnyModel | null): Promise From 2e144f064da806091ad126ca9b55e96d538d7894 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 21 May 2025 08:26:15 -0700 Subject: [PATCH 203/996] Fix syntax highlighting --- src-web/components/core/Editor/twig/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-web/components/core/Editor/twig/extension.ts b/src-web/components/core/Editor/twig/extension.ts index ddc187098..8e743deb0 100644 --- a/src-web/components/core/Editor/twig/extension.ts +++ b/src-web/components/core/Editor/twig/extension.ts @@ -72,7 +72,7 @@ function mixLanguage(base: LanguageSupport): LRLanguage { return { parser: base.language.parser, - overlay: (node) => node.type.name === 'PlainText', + overlay: (node) => node.type.name === 'Text', }; }), }); From b400940f0ee2eec2eb464078925bd5624574ead0 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 21 May 2025 11:04:57 -0700 Subject: [PATCH 204/996] Fix import curl --- src-web/hooks/useImportCurl.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src-web/hooks/useImportCurl.ts b/src-web/hooks/useImportCurl.ts index f70698bdc..f7c2fb2e4 100644 --- a/src-web/hooks/useImportCurl.ts +++ b/src-web/hooks/useImportCurl.ts @@ -1,5 +1,6 @@ -import type { HttpRequest} from '@yaakapp-internal/models'; -import { createWorkspaceModel, patchModelById } from '@yaakapp-internal/models'; +import type { HttpRequest } from '@yaakapp-internal/models'; +import { patchModelById } from '@yaakapp-internal/models'; +import { createRequestAndNavigate } from '../lib/createRequestAndNavigate'; import { jotaiStore } from '../lib/jotai'; import { invokeCmd } from '../lib/tauri'; import { showToast } from '../lib/toast'; @@ -26,7 +27,7 @@ export function useImportCurl() { let verb; if (overwriteRequestId == null) { verb = 'Created'; - await createWorkspaceModel(importedRequest); + await createRequestAndNavigate(importedRequest); } else { verb = 'Updated'; await patchModelById(importedRequest.model, overwriteRequestId, (r: HttpRequest) => ({ From 041298b3f8de8ef9db3032ea1c68f70fcf0cb7e6 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 21 May 2025 11:05:20 -0700 Subject: [PATCH 205/996] Detect JSON language if application/javascript returns JSON --- src-web/lib/contentType.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src-web/lib/contentType.ts b/src-web/lib/contentType.ts index 5f12a3666..909b949fe 100644 --- a/src-web/lib/contentType.ts +++ b/src-web/lib/contentType.ts @@ -11,7 +11,7 @@ export function languageFromContentType( } else if (justContentType.includes('xml')) { return 'xml'; } else if (justContentType.includes('html')) { - const detected = detectFromContent(content, 'html'); + const detected = detectFromContent(content); if (detected === 'xml') { // If it's detected as XML, but is already HTML, don't change it return 'html'; @@ -19,7 +19,8 @@ export function languageFromContentType( return detected; } } else if (justContentType.includes('javascript')) { - return 'javascript'; + // Sometimes `application/javascript` returns JSON, so try detecting that + return detectFromContent(content, 'javascript'); } return detectFromContent(content, 'text'); @@ -27,7 +28,7 @@ export function languageFromContentType( function detectFromContent( content: string | null, - fallback: EditorProps['language'], + fallback?: EditorProps['language'], ): EditorProps['language'] { if (content == null) return 'text'; From a6b18c23e1b72689d6f41e77cab774bb009281ad Mon Sep 17 00:00:00 2001 From: Pannawich Lohanimit <30285202+plohan@users.noreply.github.com> Date: Fri, 23 May 2025 22:11:16 +0700 Subject: [PATCH 206/996] fix: change incorrect default GraphQL request name (#213) --- src-web/lib/resolvedModelName.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src-web/lib/resolvedModelName.ts b/src-web/lib/resolvedModelName.ts index 355d6e054..9bdd11f6b 100644 --- a/src-web/lib/resolvedModelName.ts +++ b/src-web/lib/resolvedModelName.ts @@ -18,7 +18,9 @@ export function resolvedModelName(r: AnyModel | null): string { const withoutVariables = r.url.replace(/\$\{\[\s*([^\]\s]+)\s*]}/g, '$1'); if (withoutVariables.trim() === '') { return r.model === 'http_request' - ? 'HTTP Request' + ? r.bodyType && r.bodyType === 'graphql' + ? 'GraphQL Request' + : 'HTTP Request' : r.model === 'websocket_request' ? 'WebSocket Request' : 'gRPC Request'; From 13d959799ad28182d24064edd2ae9c34d118466e Mon Sep 17 00:00:00 2001 From: nguyen Date: Fri, 23 May 2025 22:12:06 +0700 Subject: [PATCH 207/996] fix: prevent button stealing focus from url input (#212) --- src-web/components/UrlBar.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src-web/components/UrlBar.tsx b/src-web/components/UrlBar.tsx index 2916cbfdb..b65cce08d 100644 --- a/src-web/components/UrlBar.tsx +++ b/src-web/components/UrlBar.tsx @@ -113,6 +113,10 @@ export const UrlBar = memo(function UrlBar({ iconColor="secondary" icon={isLoading ? 'x' : submitIcon} hotkeyAction="http_request.send" + onMouseDown={(e) => { + // Prevent the button from taking focus + e.preventDefault(); + }} />
)} From 4cd2e9cd3174e09a4578c3f35415ced27f327510 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 23 May 2025 08:13:25 -0700 Subject: [PATCH 208/996] Request Inheritance (#209) --- .../src/bindings/gen_models.ts | 10 +- .../20250516182745_default-attrs.sql | 15 ++ src-tauri/src/grpc.rs | 11 +- src-tauri/src/http_request.rs | 92 ++++++------ src-tauri/src/lib.rs | 4 +- src-tauri/src/render.rs | 4 +- .../plugins/auth-oauth2/build/index.js | 31 ++++- .../plugins/importer-curl/build/index.js | 31 +++-- src-tauri/yaak-git/bindings/gen_models.ts | 8 +- src-tauri/yaak-models/bindings/gen_models.ts | 12 +- src-tauri/yaak-models/src/models.rs | 106 +++++++++----- src-tauri/yaak-models/src/queries/folders.rs | 42 +++++- .../yaak-models/src/queries/grpc_requests.rs | 43 +++++- .../yaak-models/src/queries/http_requests.rs | 43 +++++- .../src/queries/websocket_requests.rs | 47 ++++++- .../yaak-models/src/queries/workspaces.rs | 17 ++- src-tauri/yaak-plugins/bindings/gen_models.ts | 8 +- src-tauri/yaak-plugins/src/manager.rs | 4 +- src-tauri/yaak-sync/bindings/gen_models.ts | 8 +- src-tauri/yaak-ws/src/commands.rs | 23 ++- src-web/commands/openFolderSettings.tsx | 14 ++ src-web/commands/openWorkspaceSettings.tsx | 34 ++--- src-web/components/FolderSettingsDialog.tsx | 93 ++++++++++--- src-web/components/GitDropdown.tsx | 4 +- src-web/components/GrpcRequestPane.tsx | 61 +++----- src-web/components/HeadersEditor.tsx | 95 +++++++++---- .../components/HttpAuthenticationEditor.tsx | 86 +++++++++--- src-web/components/HttpRequestPane.tsx | 56 +++----- src-web/components/RouteError.tsx | 2 +- src-web/components/WebsocketRequestPane.tsx | 52 ++----- .../components/WorkspaceActionsDropdown.tsx | 2 +- .../components/WorkspaceSettingsDialog.tsx | 131 ++++++++++++------ src-web/components/core/Checkbox.tsx | 1 + src-web/components/core/PairEditor.tsx | 30 ++-- src-web/components/core/RadioDropdown.tsx | 2 +- .../sidebar/SidebarItemContextMenu.tsx | 11 +- src-web/hooks/useAuthTab.tsx | 64 +++++++++ src-web/hooks/useHeadersTab.tsx | 31 +++++ src-web/hooks/useHttpAuthenticationConfig.ts | 14 +- src-web/hooks/useInheritedAuthentication.ts | 50 +++++++ src-web/hooks/useInheritedHeaders.ts | 46 ++++++ 41 files changed, 1033 insertions(+), 405 deletions(-) create mode 100644 src-tauri/migrations/20250516182745_default-attrs.sql create mode 100644 src-web/commands/openFolderSettings.tsx create mode 100644 src-web/hooks/useAuthTab.tsx create mode 100644 src-web/hooks/useHeadersTab.tsx create mode 100644 src-web/hooks/useInheritedAuthentication.ts create mode 100644 src-web/hooks/useInheritedHeaders.ts diff --git a/packages/plugin-runtime-types/src/bindings/gen_models.ts b/packages/plugin-runtime-types/src/bindings/gen_models.ts index a9e7794c9..9c981fc95 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_models.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_models.ts @@ -4,11 +4,9 @@ export type Environment = { model: "environment", id: string, workspaceId: strin export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id?: string, }; -export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, }; +export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, description: string, name: string, defaultAuthentication: ParentAuthentication, defaultHeaders: Array, sortPriority: number, }; -export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, id?: string, }; - -export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; +export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, body: Record, bodyType: string | null, description: string, headers: Array, method: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; @@ -22,6 +20,8 @@ export type HttpResponseState = "initialized" | "connected" | "closed"; export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, id?: string, }; +export type ParentAuthentication = { authentication: Record, authenticationType: string | null, }; + export type WebsocketRequest = { model: "websocket_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, message: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; -export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; +export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, encryptionKeyChallenge: string | null, defaultAuthentication: ParentAuthentication, defaultHeaders: Array, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; diff --git a/src-tauri/migrations/20250516182745_default-attrs.sql b/src-tauri/migrations/20250516182745_default-attrs.sql new file mode 100644 index 000000000..4b5691f2c --- /dev/null +++ b/src-tauri/migrations/20250516182745_default-attrs.sql @@ -0,0 +1,15 @@ +-- Auth +ALTER TABLE workspaces + ADD COLUMN authentication TEXT NOT NULL DEFAULT '{}'; +ALTER TABLE folders + ADD COLUMN authentication TEXT NOT NULL DEFAULT '{}'; +ALTER TABLE workspaces + ADD COLUMN authentication_type TEXT; +ALTER TABLE folders + ADD COLUMN authentication_type TEXT; + +-- Headers +ALTER TABLE workspaces + ADD COLUMN headers TEXT NOT NULL DEFAULT '[]'; +ALTER TABLE folders + ADD COLUMN headers TEXT NOT NULL DEFAULT '[]'; diff --git a/src-tauri/src/grpc.rs b/src-tauri/src/grpc.rs index 94ab06f46..52556dd5c 100644 --- a/src-tauri/src/grpc.rs +++ b/src-tauri/src/grpc.rs @@ -5,6 +5,7 @@ use KeyAndValueRef::{Ascii, Binary}; use tauri::{Manager, Runtime, WebviewWindow}; use yaak_grpc::{KeyAndValueRef, MetadataMap}; use yaak_models::models::GrpcRequest; +use yaak_models::query_manager::QueryManagerExt; use yaak_plugins::events::{CallHttpAuthenticationRequest, HttpHeader}; use yaak_plugins::manager::PluginManager; @@ -27,7 +28,8 @@ pub(crate) async fn build_metadata( let mut metadata = BTreeMap::new(); // Add the rest of metadata - for h in request.clone().metadata { + let resolved_metadata = window.db().resolve_metadata_for_grpc_request(&request)?; + for h in resolved_metadata { if h.name.is_empty() && h.value.is_empty() { continue; } @@ -39,8 +41,11 @@ pub(crate) async fn build_metadata( metadata.insert(h.name, h.value); } - if let Some(auth_name) = request.authentication_type.clone() { - let auth = request.authentication.clone(); + let (authentication_type, authentication) = + window.db().resolve_auth_for_grpc_request(&request)?; + + if let Some(auth_name) = authentication_type.clone() { + let auth = authentication.clone(); let plugin_req = CallHttpAuthenticationRequest { context_id: format!("{:x}", md5::compute(request.id.clone())), values: serde_json::from_value(serde_json::to_value(&auth).unwrap()).unwrap(), diff --git a/src-tauri/src/http_request.rs b/src-tauri/src/http_request.rs index 0b38c0c85..66f711e20 100644 --- a/src-tauri/src/http_request.rs +++ b/src-tauri/src/http_request.rs @@ -84,7 +84,7 @@ pub async fn send_http_request( } }; - let mut url_string = request.url; + let mut url_string = request.url.clone(); url_string = ensure_proto(&url_string); if !url_string.starts_with("http://") && !url_string.starts_with("https://") { @@ -227,7 +227,9 @@ pub async fn send_http_request( // ); // } - for h in request.headers.clone() { + let resolved_headers = window.db().resolve_headers_for_http_request(&request)?; + + for h in resolved_headers { if h.name.is_empty() && h.value.is_empty() { continue; } @@ -255,7 +257,7 @@ pub async fn send_http_request( } let request_body = request.body.clone(); - if let Some(body_type) = &request.body_type { + if let Some(body_type) = &request.body_type.clone() { if body_type == "graphql" { let query = get_str_h(&request_body, "query"); let variables = get_str_h(&request_body, "variables"); @@ -376,7 +378,7 @@ pub async fn send_http_request( }; } - // Set file path if it is not empty + // Set a file path if it is not empty if !file_path.is_empty() { let filename = PathBuf::from(file_path) .file_name() @@ -426,43 +428,53 @@ pub async fn send_http_request( } }; - // Apply authentication - - if let Some(auth_name) = request.authentication_type.to_owned() { - let req = CallHttpAuthenticationRequest { - context_id: format!("{:x}", md5::compute(request.id)), - values: serde_json::from_value(serde_json::to_value(&request.authentication).unwrap()) - .unwrap(), - url: sendable_req.url().to_string(), - method: sendable_req.method().to_string(), - headers: sendable_req - .headers() - .iter() - .map(|(name, value)| HttpHeader { - name: name.to_string(), - value: value.to_str().unwrap_or_default().to_string(), - }) - .collect(), - }; - let auth_result = plugin_manager.call_http_authentication(&window, &auth_name, req).await; - let plugin_result = match auth_result { - Ok(r) => r, - Err(e) => { - return Ok(response_err( - &app_handle, - &*response.lock().await, - e.to_string(), - &update_source, - )); - } - }; + let (authentication_type, authentication) = + window.db().resolve_auth_for_http_request(&request)?; + + match authentication_type { + None => { + // No authentication found. Not even inherited + } + Some(authentication_type) if authentication_type == "none" => { + // Explicitly no authentication + } + Some(authentication_type) => { + let req = CallHttpAuthenticationRequest { + context_id: format!("{:x}", md5::compute(request.id)), + values: serde_json::from_value(serde_json::to_value(&authentication).unwrap()) + .unwrap(), + url: sendable_req.url().to_string(), + method: sendable_req.method().to_string(), + headers: sendable_req + .headers() + .iter() + .map(|(name, value)| HttpHeader { + name: name.to_string(), + value: value.to_str().unwrap_or_default().to_string(), + }) + .collect(), + }; + let auth_result = + plugin_manager.call_http_authentication(&window, &authentication_type, req).await; + let plugin_result = match auth_result { + Ok(r) => r, + Err(e) => { + return Ok(response_err( + &app_handle, + &*response.lock().await, + e.to_string(), + &update_source, + )); + } + }; - let headers = sendable_req.headers_mut(); - for header in plugin_result.set_headers { - headers.insert( - HeaderName::from_str(&header.name).unwrap(), - HeaderValue::from_str(&header.value).unwrap(), - ); + let headers = sendable_req.headers_mut(); + for header in plugin_result.set_headers { + headers.insert( + HeaderName::from_str(&header.name).unwrap(), + HeaderValue::from_str(&header.value).unwrap(), + ); + } } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 000d37727..d9752c9e8 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -917,10 +917,10 @@ async fn cmd_call_http_authentication_action( auth_name: &str, action_index: i32, values: HashMap, - request_id: &str, + model_id: &str, ) -> YaakResult<()> { Ok(plugin_manager - .call_http_authentication_action(&window, auth_name, action_index, values, request_id) + .call_http_authentication_action(&window, auth_name, action_index, values, model_id) .await?) } diff --git a/src-tauri/src/render.rs b/src-tauri/src/render.rs index 08f3efb0d..6efd6a0e6 100644 --- a/src-tauri/src/render.rs +++ b/src-tauri/src/render.rs @@ -2,7 +2,7 @@ use serde_json::Value; use std::collections::{BTreeMap, HashMap}; use yaak_http::apply_path_placeholders; use yaak_models::models::{ - Environment, GrpcMetadataEntry, GrpcRequest, HttpRequest, HttpRequestHeader, HttpUrlParameter, + Environment, GrpcRequest, HttpRequest, HttpRequestHeader, HttpUrlParameter, }; use yaak_models::render::make_vars_hashmap; use yaak_templates::{parse_and_render, render_json_value_raw, TemplateCallback}; @@ -37,7 +37,7 @@ pub async fn render_grpc_request( let mut metadata = Vec::new(); for p in r.metadata.clone() { - metadata.push(GrpcMetadataEntry { + metadata.push(HttpRequestHeader { enabled: p.enabled, name: render(p.name.as_str(), vars, cb).await?, value: render(p.value.as_str(), vars, cb).await?, diff --git a/src-tauri/vendored/plugins/auth-oauth2/build/index.js b/src-tauri/vendored/plugins/auth-oauth2/build/index.js index 9669d5305..03a8094d8 100644 --- a/src-tauri/vendored/plugins/auth-oauth2/build/index.js +++ b/src-tauri/vendored/plugins/auth-oauth2/build/index.js @@ -32,6 +32,7 @@ var import_node_fs = require("node:fs"); async function getAccessToken(ctx, { accessTokenUrl, scope, + audience, params, grantType, credentialsInBody, @@ -56,6 +57,7 @@ async function getAccessToken(ctx, { ] }; if (scope) httpRequest.body.form.push({ name: "scope", value: scope }); + if (scope) httpRequest.body.form.push({ name: "audience", value: audience }); if (credentialsInBody) { httpRequest.body.form.push({ name: "client_id", value: clientId }); httpRequest.body.form.push({ name: "client_secret", value: clientSecret }); @@ -64,10 +66,10 @@ async function getAccessToken(ctx, { httpRequest.headers.push({ name: "Authorization", value }); } const resp = await ctx.httpRequest.send({ httpRequest }); + const body = resp.bodyPath ? (0, import_node_fs.readFileSync)(resp.bodyPath, "utf8") : ""; if (resp.status < 200 || resp.status >= 300) { - throw new Error("Failed to fetch access token with status=" + resp.status); + throw new Error("Failed to fetch access token with status=" + resp.status + " and body=" + body); } - const body = (0, import_node_fs.readFileSync)(resp.bodyPath ?? "", "utf8"); let response; try { response = JSON.parse(body); @@ -168,10 +170,10 @@ async function getOrRefreshAccessToken(ctx, contextId, { await deleteToken(ctx, contextId); return null; } + const body = resp.bodyPath ? (0, import_node_fs2.readFileSync)(resp.bodyPath, "utf8") : ""; if (resp.status < 200 || resp.status >= 300) { - throw new Error("Failed to fetch access token with status=" + resp.status); + throw new Error("Failed to refresh access token with status=" + resp.status + " and body=" + body); } - const body = (0, import_node_fs2.readFileSync)(resp.bodyPath ?? "", "utf8"); let response; try { response = JSON.parse(body); @@ -201,6 +203,7 @@ async function getAuthorizationCode(ctx, contextId, { redirectUri, scope, state, + audience, credentialsInBody, pkce }) { @@ -220,6 +223,7 @@ async function getAuthorizationCode(ctx, contextId, { if (redirectUri) authorizationUrl.searchParams.set("redirect_uri", redirectUri); if (scope) authorizationUrl.searchParams.set("scope", scope); if (state) authorizationUrl.searchParams.set("state", state); + if (audience) authorizationUrl.searchParams.set("audience", audience); if (pkce) { const verifier = pkce.codeVerifier || createPkceCodeVerifier(); const challengeMethod = pkce.challengeMethod || DEFAULT_PKCE_METHOD; @@ -256,6 +260,7 @@ async function getAuthorizationCode(ctx, contextId, { clientId, clientSecret, scope, + audience, credentialsInBody, params: [ { name: "code", value: code }, @@ -291,6 +296,7 @@ async function getClientCredentials(ctx, contextId, { clientId, clientSecret, scope, + audience, credentialsInBody }) { const token = await getToken(ctx, contextId); @@ -299,6 +305,7 @@ async function getClientCredentials(ctx, contextId, { const response = await getAccessToken(ctx, { grantType: "client_credentials", accessTokenUrl, + audience, clientId, clientSecret, scope, @@ -315,7 +322,8 @@ function getImplicit(ctx, contextId, { clientId, redirectUri, scope, - state + state, + audience }) { return new Promise(async (resolve, reject) => { const token = await getToken(ctx, contextId); @@ -327,6 +335,7 @@ function getImplicit(ctx, contextId, { if (redirectUri) authorizationUrl.searchParams.set("redirect_uri", redirectUri); if (scope) authorizationUrl.searchParams.set("scope", scope); if (state) authorizationUrl.searchParams.set("state", state); + if (audience) authorizationUrl.searchParams.set("audience", audience); if (responseType.includes("id_token")) { authorizationUrl.searchParams.set("nonce", String(Math.floor(Math.random() * 9999999999999) + 1)); } @@ -366,6 +375,7 @@ async function getPassword(ctx, contextId, { username, password, credentialsInBody, + audience, scope }) { const token = await getOrRefreshAccessToken(ctx, contextId, { @@ -383,6 +393,7 @@ async function getPassword(ctx, contextId, { clientId, clientSecret, scope, + audience, grantType: "password", credentialsInBody, params: [ @@ -530,6 +541,12 @@ var plugin = { optional: true, dynamic: hiddenIfNot(["authorization_code", "implicit"]) }, + { + type: "text", + name: "audience", + label: "Audience", + optional: true + }, { type: "checkbox", name: "usePkce", @@ -635,6 +652,7 @@ var plugin = { clientSecret: stringArg(values, "clientSecret"), redirectUri: stringArgOrNull(values, "redirectUri"), scope: stringArgOrNull(values, "scope"), + audience: stringArgOrNull(values, "audience"), state: stringArgOrNull(values, "state"), credentialsInBody, pkce: values.usePkce ? { @@ -650,6 +668,7 @@ var plugin = { redirectUri: stringArgOrNull(values, "redirectUri"), responseType: stringArg(values, "responseType"), scope: stringArgOrNull(values, "scope"), + audience: stringArgOrNull(values, "audience"), state: stringArgOrNull(values, "state") }); } else if (grantType === "client_credentials") { @@ -659,6 +678,7 @@ var plugin = { clientId: stringArg(values, "clientId"), clientSecret: stringArg(values, "clientSecret"), scope: stringArgOrNull(values, "scope"), + audience: stringArgOrNull(values, "audience"), credentialsInBody }); } else if (grantType === "password") { @@ -670,6 +690,7 @@ var plugin = { username: stringArg(values, "username"), password: stringArg(values, "password"), scope: stringArgOrNull(values, "scope"), + audience: stringArgOrNull(values, "audience"), credentialsInBody }); } else { diff --git a/src-tauri/vendored/plugins/importer-curl/build/index.js b/src-tauri/vendored/plugins/importer-curl/build/index.js index 1f94ee392..23d09ea5a 100644 --- a/src-tauri/vendored/plugins/importer-curl/build/index.js +++ b/src-tauri/vendored/plugins/importer-curl/build/index.js @@ -542,20 +542,23 @@ function pairsToDataParameters(keyedPairs) { } for (const p of pairs) { if (typeof p !== "string") continue; - const [name, value] = p.split("="); - if (p.startsWith("@")) { - dataParameters.push({ - name: name ?? "", - value: "", - filePath: p.slice(1), - enabled: true - }); - } else { - dataParameters.push({ - name: name ?? "", - value: flagName === "data-urlencode" ? encodeURIComponent(value ?? "") : value ?? "", - enabled: true - }); + let params = p.split("&"); + for (const param of params) { + const [name, value] = param.split("="); + if (param.startsWith("@")) { + dataParameters.push({ + name: name ?? "", + value: "", + filePath: param.slice(1), + enabled: true + }); + } else { + dataParameters.push({ + name: name ?? "", + value: flagName === "data-urlencode" ? encodeURIComponent(value ?? "") : value ?? "", + enabled: true + }); + } } } } diff --git a/src-tauri/yaak-git/bindings/gen_models.ts b/src-tauri/yaak-git/bindings/gen_models.ts index 3118c4146..b51a6b75e 100644 --- a/src-tauri/yaak-git/bindings/gen_models.ts +++ b/src-tauri/yaak-git/bindings/gen_models.ts @@ -4,11 +4,9 @@ export type Environment = { model: "environment", id: string, workspaceId: strin export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id?: string, }; -export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, }; +export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, name: string, sortPriority: number, }; -export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, id?: string, }; - -export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; +export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, body: Record, bodyType: string | null, description: string, headers: Array, method: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; @@ -20,4 +18,4 @@ export type SyncModel = { "type": "workspace" } & Workspace | { "type": "environ export type WebsocketRequest = { model: "websocket_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, message: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; -export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; +export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, authentication: Record, authenticationType: string | null, description: string, headers: Array, name: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; diff --git a/src-tauri/yaak-models/bindings/gen_models.ts b/src-tauri/yaak-models/bindings/gen_models.ts index 7e5e0e609..bd1b9c844 100644 --- a/src-tauri/yaak-models/bindings/gen_models.ts +++ b/src-tauri/yaak-models/bindings/gen_models.ts @@ -18,7 +18,7 @@ export type Environment = { model: "environment", id: string, workspaceId: strin export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id?: string, }; -export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, }; +export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, name: string, sortPriority: number, }; export type GrpcConnection = { model: "grpc_connection", id: string, createdAt: string, updatedAt: string, workspaceId: string, requestId: string, elapsed: number, error: string | null, method: string, service: string, status: number, state: GrpcConnectionState, trailers: { [key in string]?: string }, url: string, }; @@ -28,9 +28,7 @@ export type GrpcEvent = { model: "grpc_event", id: string, createdAt: string, up export type GrpcEventType = "info" | "error" | "client_message" | "server_message" | "connection_start" | "connection_end"; -export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, id?: string, }; - -export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; +export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, body: Record, bodyType: string | null, description: string, headers: Array, method: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; @@ -50,6 +48,10 @@ export type ModelChangeEvent = { "type": "upsert" } | { "type": "delete" }; export type ModelPayload = { model: AnyModel, updateSource: UpdateSource, change: ModelChangeEvent, }; +export type ParentAuthentication = { authentication: Record, authenticationType: string | null, }; + +export type ParentHeaders = { headers: Array, }; + export type Plugin = { model: "plugin", id: string, createdAt: string, updatedAt: string, checkedAt: string | null, directory: string, enabled: boolean, url: string | null, }; export type PluginKeyValue = { model: "plugin_key_value", createdAt: string, updatedAt: string, pluginName: string, key: string, value: string, }; @@ -76,6 +78,6 @@ export type WebsocketMessageType = "text" | "binary"; export type WebsocketRequest = { model: "websocket_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, message: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; -export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; +export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, authentication: Record, authenticationType: string | null, description: string, headers: Array, name: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; export type WorkspaceMeta = { model: "workspace_meta", id: string, workspaceId: string, createdAt: string, updatedAt: string, encryptionKey: EncryptedKey | null, settingSyncDir: string | null, }; diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index 7a5f24efa..f6c7f2451 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -219,8 +219,13 @@ pub struct Workspace { pub id: String, pub created_at: NaiveDateTime, pub updated_at: NaiveDateTime, - pub name: String, + + #[ts(type = "Record")] + pub authentication: BTreeMap, + pub authentication_type: Option, pub description: String, + pub headers: Vec, + pub name: String, pub encryption_key_challenge: Option, // Settings @@ -261,6 +266,9 @@ impl UpsertModelInfo for Workspace { (CreatedAt, upsert_date(source, self.created_at)), (UpdatedAt, upsert_date(source, self.updated_at)), (Name, self.name.trim().into()), + (Authentication, serde_json::to_string(&self.authentication)?.into()), + (AuthenticationType, self.authentication_type.into()), + (Headers, serde_json::to_string(&self.headers)?.into()), (Description, self.description.into()), (EncryptionKeyChallenge, self.encryption_key_challenge.into()), (SettingFollowRedirects, self.setting_follow_redirects.into()), @@ -273,6 +281,9 @@ impl UpsertModelInfo for Workspace { vec![ WorkspaceIden::UpdatedAt, WorkspaceIden::Name, + WorkspaceIden::Authentication, + WorkspaceIden::AuthenticationType, + WorkspaceIden::Headers, WorkspaceIden::Description, WorkspaceIden::EncryptionKeyChallenge, WorkspaceIden::SettingRequestTimeout, @@ -286,6 +297,8 @@ impl UpsertModelInfo for Workspace { where Self: Sized, { + let headers: String = row.get("headers")?; + let authentication: String = row.get("authentication")?; Ok(Self { id: row.get("id")?, model: row.get("model")?, @@ -294,6 +307,9 @@ impl UpsertModelInfo for Workspace { name: row.get("name")?, description: row.get("description")?, encryption_key_challenge: row.get("encryption_key_challenge")?, + headers: serde_json::from_str(&headers).unwrap_or_default(), + authentication: serde_json::from_str(&authentication).unwrap_or_default(), + authentication_type: row.get("authentication_type")?, setting_follow_redirects: row.get("setting_follow_redirects")?, setting_request_timeout: row.get("setting_request_timeout")?, setting_validate_certificates: row.get("setting_validate_certificates")?, @@ -581,6 +597,22 @@ pub struct EnvironmentVariable { pub id: Option, } +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] +#[serde(default, rename_all = "camelCase")] +#[ts(export, export_to = "gen_models.ts")] +pub struct ParentAuthentication { + #[ts(type = "Record")] + pub authentication: BTreeMap, + pub authentication_type: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] +#[serde(default, rename_all = "camelCase")] +#[ts(export, export_to = "gen_models.ts")] +pub struct ParentHeaders { + pub headers: Vec, +} + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] @@ -594,8 +626,12 @@ pub struct Folder { pub workspace_id: String, pub folder_id: Option, - pub name: String, + #[ts(type = "Record")] + pub authentication: BTreeMap, + pub authentication_type: Option, pub description: String, + pub headers: Vec, + pub name: String, pub sort_priority: f32, } @@ -630,8 +666,11 @@ impl UpsertModelInfo for Folder { (UpdatedAt, upsert_date(source, self.updated_at)), (WorkspaceId, self.workspace_id.into()), (FolderId, self.folder_id.into()), - (Name, self.name.trim().into()), + (Authentication, serde_json::to_string(&self.authentication)?.into()), + (AuthenticationType, self.authentication_type.into()), + (Headers, serde_json::to_string(&self.headers)?.into()), (Description, self.description.into()), + (Name, self.name.trim().into()), (SortPriority, self.sort_priority.into()), ]) } @@ -640,6 +679,9 @@ impl UpsertModelInfo for Folder { vec![ FolderIden::UpdatedAt, FolderIden::Name, + FolderIden::Authentication, + FolderIden::AuthenticationType, + FolderIden::Headers, FolderIden::Description, FolderIden::FolderId, FolderIden::SortPriority, @@ -650,6 +692,8 @@ impl UpsertModelInfo for Folder { where Self: Sized, { + let headers: String = row.get("headers")?; + let authentication: String = row.get("authentication")?; Ok(Self { id: row.get("id")?, model: row.get("model")?, @@ -660,6 +704,9 @@ impl UpsertModelInfo for Folder { folder_id: row.get("folder_id")?, name: row.get("name")?, description: row.get("description")?, + headers: serde_json::from_str(&headers).unwrap_or_default(), + authentication_type: row.get("authentication_type")?, + authentication: serde_json::from_str(&authentication).unwrap_or_default(), }) } } @@ -782,28 +829,28 @@ impl UpsertModelInfo for HttpRequest { ] } - fn from_row(r: &Row) -> rusqlite::Result { - let url_parameters: String = r.get("url_parameters")?; - let body: String = r.get("body")?; - let authentication: String = r.get("authentication")?; - let headers: String = r.get("headers")?; + fn from_row(row: &Row) -> rusqlite::Result { + let url_parameters: String = row.get("url_parameters")?; + let body: String = row.get("body")?; + let authentication: String = row.get("authentication")?; + let headers: String = row.get("headers")?; Ok(Self { - id: r.get("id")?, - model: r.get("model")?, - workspace_id: r.get("workspace_id")?, - created_at: r.get("created_at")?, - updated_at: r.get("updated_at")?, + id: row.get("id")?, + model: row.get("model")?, + workspace_id: row.get("workspace_id")?, + created_at: row.get("created_at")?, + updated_at: row.get("updated_at")?, authentication: serde_json::from_str(authentication.as_str()).unwrap_or_default(), - authentication_type: r.get("authentication_type")?, + authentication_type: row.get("authentication_type")?, body: serde_json::from_str(body.as_str()).unwrap_or_default(), - body_type: r.get("body_type")?, - description: r.get("description")?, - folder_id: r.get("folder_id")?, + body_type: row.get("body_type")?, + description: row.get("description")?, + folder_id: row.get("folder_id")?, headers: serde_json::from_str(headers.as_str()).unwrap_or_default(), - method: r.get("method")?, - name: r.get("name")?, - sort_priority: r.get("sort_priority")?, - url: r.get("url")?, + method: row.get("method")?, + name: row.get("name")?, + sort_priority: row.get("sort_priority")?, + url: row.get("url")?, url_parameters: serde_json::from_str(url_parameters.as_str()).unwrap_or_default(), }) } @@ -992,7 +1039,7 @@ impl UpsertModelInfo for WebsocketRequest { (WorkspaceId, self.workspace_id.into()), (FolderId, self.folder_id.as_ref().map(|s| s.as_str()).into()), (Authentication, serde_json::to_string(&self.authentication)?.into()), - (AuthenticationType, self.authentication_type.as_ref().map(|s| s.as_str()).into()), + (AuthenticationType, self.authentication_type.into()), (Description, self.description.into()), (Headers, serde_json::to_string(&self.headers)?.into()), (Message, self.message.into()), @@ -1295,19 +1342,6 @@ impl UpsertModelInfo for HttpResponse { } } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] -#[serde(default, rename_all = "camelCase")] -#[ts(export, export_to = "gen_models.ts")] -pub struct GrpcMetadataEntry { - #[serde(default = "default_true")] - #[ts(optional, as = "Option")] - pub enabled: bool, - pub name: String, - pub value: String, - #[ts(optional, as = "Option")] - pub id: Option, -} - #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] @@ -1326,7 +1360,7 @@ pub struct GrpcRequest { pub authentication: BTreeMap, pub description: String, pub message: String, - pub metadata: Vec, + pub metadata: Vec, pub method: Option, pub name: String, pub service: Option, diff --git a/src-tauri/yaak-models/src/queries/folders.rs b/src-tauri/yaak-models/src/queries/folders.rs index 1d9e508bb..9005ce38d 100644 --- a/src-tauri/yaak-models/src/queries/folders.rs +++ b/src-tauri/yaak-models/src/queries/folders.rs @@ -2,10 +2,12 @@ use crate::connection_or_tx::ConnectionOrTx; use crate::db_context::DbContext; use crate::error::Result; use crate::models::{ - Folder, FolderIden, GrpcRequest, GrpcRequestIden, HttpRequest, HttpRequestIden, - WebsocketRequest, WebsocketRequestIden, + Folder, FolderIden, GrpcRequest, GrpcRequestIden, HttpRequest, HttpRequestHeader, + HttpRequestIden, WebsocketRequest, WebsocketRequestIden, }; use crate::util::UpdateSource; +use serde_json::Value; +use std::collections::BTreeMap; impl<'a> DbContext<'a> { pub fn get_folder(&self, id: &str) -> Result { @@ -110,4 +112,40 @@ impl<'a> DbContext<'a> { Ok(new_folder) } + + pub fn resolve_auth_for_folder( + &self, + folder: Folder, + ) -> Result<(Option, BTreeMap)> { + if let Some(at) = folder.authentication_type { + return Ok((Some(at), folder.authentication)); + } + + if let Some(folder_id) = folder.folder_id { + let folder = self.get_folder(&folder_id)?; + return self.resolve_auth_for_folder(folder); + } + + let workspace = self.get_workspace(&folder.workspace_id)?; + Ok(self.resolve_auth_for_workspace(&workspace)) + } + + pub fn resolve_headers_for_folder(&self, folder: &Folder) -> Result> { + let mut headers = Vec::new(); + + if let Some(folder_id) = folder.folder_id.clone() { + let parent_folder = self.get_folder(&folder_id)?; + let mut folder_headers = self.resolve_headers_for_folder(&parent_folder)?; + // NOTE: Add parent headers first, so overrides are logical + headers.append(&mut folder_headers); + } else { + let workspace = self.get_workspace(&folder.workspace_id)?; + let mut workspace_headers = self.resolve_headers_for_workspace(&workspace); + headers.append(&mut workspace_headers); + } + + headers.append(&mut folder.headers.clone()); + + Ok(headers) + } } diff --git a/src-tauri/yaak-models/src/queries/grpc_requests.rs b/src-tauri/yaak-models/src/queries/grpc_requests.rs index 7116fb893..0c8e056b4 100644 --- a/src-tauri/yaak-models/src/queries/grpc_requests.rs +++ b/src-tauri/yaak-models/src/queries/grpc_requests.rs @@ -1,7 +1,9 @@ use crate::db_context::DbContext; use crate::error::Result; -use crate::models::{GrpcRequest, GrpcRequestIden}; +use crate::models::{GrpcRequest, GrpcRequestIden, HttpRequestHeader}; use crate::util::UpdateSource; +use serde_json::Value; +use std::collections::BTreeMap; impl<'a> DbContext<'a> { pub fn get_grpc_request(&self, id: &str) -> Result { @@ -48,4 +50,43 @@ impl<'a> DbContext<'a> { ) -> Result { self.upsert(grpc_request, source) } + + pub fn resolve_auth_for_grpc_request( + &self, + grpc_request: &GrpcRequest, + ) -> Result<(Option, BTreeMap)> { + if let Some(at) = grpc_request.authentication_type.clone() { + return Ok((Some(at), grpc_request.authentication.clone())); + } + + if let Some(folder_id) = grpc_request.folder_id.clone() { + let folder = self.get_folder(&folder_id)?; + return self.resolve_auth_for_folder(folder); + } + + let workspace = self.get_workspace(&grpc_request.workspace_id)?; + Ok(self.resolve_auth_for_workspace(&workspace)) + } + + pub fn resolve_metadata_for_grpc_request( + &self, + grpc_request: &GrpcRequest, + ) -> Result> { + // Resolved headers should be from furthest to closest ancestor, to override logically. + let mut metadata = Vec::new(); + + if let Some(folder_id) = grpc_request.folder_id.clone() { + let parent_folder = self.get_folder(&folder_id)?; + let mut folder_headers = self.resolve_headers_for_folder(&parent_folder)?; + metadata.append(&mut folder_headers); + } else { + let workspace = self.get_workspace(&grpc_request.workspace_id)?; + let mut workspace_metadata = self.resolve_headers_for_workspace(&workspace); + metadata.append(&mut workspace_metadata); + } + + metadata.append(&mut grpc_request.metadata.clone()); + + Ok(metadata) + } } diff --git a/src-tauri/yaak-models/src/queries/http_requests.rs b/src-tauri/yaak-models/src/queries/http_requests.rs index 777a25b42..5db8beea9 100644 --- a/src-tauri/yaak-models/src/queries/http_requests.rs +++ b/src-tauri/yaak-models/src/queries/http_requests.rs @@ -1,7 +1,9 @@ use crate::db_context::DbContext; use crate::error::Result; -use crate::models::{HttpRequest, HttpRequestIden}; +use crate::models::{HttpRequest, HttpRequestHeader, HttpRequestIden}; use crate::util::UpdateSource; +use serde_json::Value; +use std::collections::BTreeMap; impl<'a> DbContext<'a> { pub fn get_http_request(&self, id: &str) -> Result { @@ -48,4 +50,43 @@ impl<'a> DbContext<'a> { ) -> Result { self.upsert(http_request, source) } + + pub fn resolve_auth_for_http_request( + &self, + http_request: &HttpRequest, + ) -> Result<(Option, BTreeMap)> { + if let Some(at) = http_request.authentication_type.clone() { + return Ok((Some(at), http_request.authentication.clone())); + } + + if let Some(folder_id) = http_request.folder_id.clone() { + let folder = self.get_folder(&folder_id)?; + return self.resolve_auth_for_folder(folder); + } + + let workspace = self.get_workspace(&http_request.workspace_id)?; + Ok(self.resolve_auth_for_workspace(&workspace)) + } + + pub fn resolve_headers_for_http_request( + &self, + http_request: &HttpRequest, + ) -> Result> { + // Resolved headers should be from furthest to closest ancestor, to override logically. + let mut headers = Vec::new(); + + if let Some(folder_id) = http_request.folder_id.clone() { + let parent_folder = self.get_folder(&folder_id)?; + let mut folder_headers = self.resolve_headers_for_folder(&parent_folder)?; + headers.append(&mut folder_headers); + } else { + let workspace = self.get_workspace(&http_request.workspace_id)?; + let mut workspace_headers = self.resolve_headers_for_workspace(&workspace); + headers.append(&mut workspace_headers); + } + + headers.append(&mut http_request.headers.clone()); + + Ok(headers) + } } diff --git a/src-tauri/yaak-models/src/queries/websocket_requests.rs b/src-tauri/yaak-models/src/queries/websocket_requests.rs index 3d4784dd9..098796f3d 100644 --- a/src-tauri/yaak-models/src/queries/websocket_requests.rs +++ b/src-tauri/yaak-models/src/queries/websocket_requests.rs @@ -1,7 +1,9 @@ use crate::db_context::DbContext; use crate::error::Result; -use crate::models::{WebsocketRequest, WebsocketRequestIden}; +use crate::models::{HttpRequestHeader, WebsocketRequest, WebsocketRequestIden}; use crate::util::UpdateSource; +use serde_json::Value; +use std::collections::BTreeMap; impl<'a> DbContext<'a> { pub fn get_websocket_request(&self, id: &str) -> Result { @@ -48,4 +50,47 @@ impl<'a> DbContext<'a> { ) -> Result { self.upsert(websocket_request, source) } + + pub fn resolve_auth_for_websocket_request( + &self, + websocket_request: &WebsocketRequest, + ) -> Result<(Option, BTreeMap)> { + if let Some(at) = websocket_request.authentication_type.clone() { + return Ok((Some(at), websocket_request.authentication.clone())); + } + + if let Some(folder_id) = websocket_request.folder_id.clone() { + let folder = self.get_folder(&folder_id)?; + return self.resolve_auth_for_folder(folder); + } + + let workspace = self.get_workspace(&websocket_request.workspace_id)?; + Ok(self.resolve_auth_for_workspace(&workspace)) + } + + pub fn resolve_headers_for_websocket_request( + &self, + websocket_request: &WebsocketRequest, + ) -> Result> { + let workspace = self.get_workspace(&websocket_request.workspace_id)?; + + // Resolved headers should be from furthest to closest ancestor, to override logically. + let mut headers = Vec::new(); + + headers.append(&mut workspace.headers.clone()); + + if let Some(folder_id) = websocket_request.folder_id.clone() { + let parent_folder = self.get_folder(&folder_id)?; + let mut folder_headers = self.resolve_headers_for_folder(&parent_folder)?; + headers.append(&mut folder_headers); + } else { + let workspace = self.get_workspace(&websocket_request.workspace_id)?; + let mut workspace_headers = self.resolve_headers_for_workspace(&workspace); + headers.append(&mut workspace_headers); + } + + headers.append(&mut websocket_request.headers.clone()); + + Ok(headers) + } } diff --git a/src-tauri/yaak-models/src/queries/workspaces.rs b/src-tauri/yaak-models/src/queries/workspaces.rs index 58f773ad3..5ec80b9f9 100644 --- a/src-tauri/yaak-models/src/queries/workspaces.rs +++ b/src-tauri/yaak-models/src/queries/workspaces.rs @@ -1,10 +1,12 @@ use crate::db_context::DbContext; use crate::error::Result; use crate::models::{ - EnvironmentIden, FolderIden, GrpcRequestIden, HttpRequestIden, WebsocketRequestIden, Workspace, - WorkspaceIden, + EnvironmentIden, FolderIden, GrpcRequestIden, HttpRequestHeader, HttpRequestIden, + WebsocketRequestIden, Workspace, WorkspaceIden, }; use crate::util::UpdateSource; +use serde_json::Value; +use std::collections::BTreeMap; impl<'a> DbContext<'a> { pub fn get_workspace(&self, id: &str) -> Result { @@ -65,4 +67,15 @@ impl<'a> DbContext<'a> { pub fn upsert_workspace(&self, w: &Workspace, source: &UpdateSource) -> Result { self.upsert(w, source) } + + pub fn resolve_auth_for_workspace( + &self, + workspace: &Workspace, + ) -> (Option, BTreeMap) { + (workspace.authentication_type.clone(), workspace.authentication.clone()) + } + + pub fn resolve_headers_for_workspace(&self, workspace: &Workspace) -> Vec { + workspace.headers.clone() + } } diff --git a/src-tauri/yaak-plugins/bindings/gen_models.ts b/src-tauri/yaak-plugins/bindings/gen_models.ts index a9e7794c9..8d95d78f7 100644 --- a/src-tauri/yaak-plugins/bindings/gen_models.ts +++ b/src-tauri/yaak-plugins/bindings/gen_models.ts @@ -4,11 +4,9 @@ export type Environment = { model: "environment", id: string, workspaceId: strin export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id?: string, }; -export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, }; +export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, name: string, sortPriority: number, }; -export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, id?: string, }; - -export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; +export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, body: Record, bodyType: string | null, description: string, headers: Array, method: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; @@ -24,4 +22,4 @@ export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, export type WebsocketRequest = { model: "websocket_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, message: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; -export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; +export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, authentication: Record, authenticationType: string | null, description: string, headers: Array, name: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; diff --git a/src-tauri/yaak-plugins/src/manager.rs b/src-tauri/yaak-plugins/src/manager.rs index 7190bcd81..fb708a2c4 100644 --- a/src-tauri/yaak-plugins/src/manager.rs +++ b/src-tauri/yaak-plugins/src/manager.rs @@ -537,7 +537,7 @@ impl PluginManager { auth_name: &str, action_index: i32, values: HashMap, - request_id: &str, + model_id: &str, ) -> Result<()> { let results = self.get_http_authentication_summaries(window).await?; let plugin = results @@ -545,7 +545,7 @@ impl PluginManager { .find_map(|(p, r)| if r.name == auth_name { Some(p) } else { None }) .ok_or(PluginNotFoundErr(auth_name.into()))?; - let context_id = format!("{:x}", md5::compute(request_id.to_string())); + let context_id = format!("{:x}", md5::compute(model_id.to_string())); self.send_to_plugin_and_wait( &PluginWindowContext::new(window), &plugin, diff --git a/src-tauri/yaak-sync/bindings/gen_models.ts b/src-tauri/yaak-sync/bindings/gen_models.ts index 8a77ba00e..3828f880c 100644 --- a/src-tauri/yaak-sync/bindings/gen_models.ts +++ b/src-tauri/yaak-sync/bindings/gen_models.ts @@ -4,11 +4,9 @@ export type Environment = { model: "environment", id: string, workspaceId: strin export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id?: string, }; -export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, }; +export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, name: string, sortPriority: number, }; -export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, id?: string, }; - -export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; +export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, body: Record, bodyType: string | null, description: string, headers: Array, method: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; @@ -22,4 +20,4 @@ export type SyncState = { model: "sync_state", id: string, workspaceId: string, export type WebsocketRequest = { model: "websocket_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, message: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; -export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; +export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, authentication: Record, authenticationType: string | null, description: string, headers: Array, name: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; diff --git a/src-tauri/yaak-ws/src/commands.rs b/src-tauri/yaak-ws/src/commands.rs index c1de4f80d..11429a451 100644 --- a/src-tauri/yaak-ws/src/commands.rs +++ b/src-tauri/yaak-ws/src/commands.rs @@ -206,9 +206,28 @@ pub(crate) async fn connect( ) .await?; + let (authentication_type, authentication) = + window.db().resolve_auth_for_websocket_request(&request)?; + let mut headers = HeaderMap::new(); - if let Some(auth_name) = request.authentication_type.clone() { - let auth = request.authentication.clone(); + + let resolved_headers = window.db().resolve_headers_for_websocket_request(&request)?; + for h in resolved_headers { + if h.name.is_empty() && h.value.is_empty() { + continue; + } + + if !h.enabled { + continue; + } + headers.insert( + HeaderName::from_str(&h.name).unwrap(), + HeaderValue::from_str(&h.value).unwrap(), + ); + } + + if let Some(auth_name) = authentication_type.clone() { + let auth = authentication.clone(); let plugin_req = CallHttpAuthenticationRequest { context_id: format!("{:x}", md5::compute(request_id.to_string())), values: serde_json::from_value(serde_json::to_value(&auth).unwrap()).unwrap(), diff --git a/src-web/commands/openFolderSettings.tsx b/src-web/commands/openFolderSettings.tsx new file mode 100644 index 000000000..06ab98cbe --- /dev/null +++ b/src-web/commands/openFolderSettings.tsx @@ -0,0 +1,14 @@ +import type { FolderSettingsTab } from '../components/FolderSettingsDialog'; +import { FolderSettingsDialog } from '../components/FolderSettingsDialog'; +import { showDialog } from '../lib/dialog'; + +export function openFolderSettings(folderId: string, tab?: FolderSettingsTab) { + showDialog({ + id: 'folder-settings', + title: 'Folder Settings', + size: 'lg', + className: 'h-[50rem]', + noPadding: true, + render: () => , + }); +} diff --git a/src-web/commands/openWorkspaceSettings.tsx b/src-web/commands/openWorkspaceSettings.tsx index 336e5eb00..48ae0682b 100644 --- a/src-web/commands/openWorkspaceSettings.tsx +++ b/src-web/commands/openWorkspaceSettings.tsx @@ -1,20 +1,22 @@ -import { WorkspaceSettingsDialog } from '../components/WorkspaceSettingsDialog'; +import type { + WorkspaceSettingsTab} from '../components/WorkspaceSettingsDialog'; +import { + WorkspaceSettingsDialog +} from '../components/WorkspaceSettingsDialog'; import { activeWorkspaceIdAtom } from '../hooks/useActiveWorkspace'; -import { createFastMutation } from '../hooks/useFastMutation'; import { showDialog } from '../lib/dialog'; import { jotaiStore } from '../lib/jotai'; -export const openWorkspaceSettings = createFastMutation({ - mutationKey: ['open_workspace_settings'], - async mutationFn() { - const workspaceId = jotaiStore.get(activeWorkspaceIdAtom); - showDialog({ - id: 'workspace-settings', - title: 'Workspace Settings', - size: 'md', - render({ hide }) { - return ; - }, - }); - }, -}); +export function openWorkspaceSettings(tab?: WorkspaceSettingsTab) { + const workspaceId = jotaiStore.get(activeWorkspaceIdAtom); + showDialog({ + id: 'workspace-settings', + title: 'Workspace Settings', + size: 'lg', + className: 'h-[50rem]', + noPadding: true, + render({ hide }) { + return ; + }, + }); +} diff --git a/src-web/components/FolderSettingsDialog.tsx b/src-web/components/FolderSettingsDialog.tsx index a6b65dfe2..0d9ff6b57 100644 --- a/src-web/components/FolderSettingsDialog.tsx +++ b/src-web/components/FolderSettingsDialog.tsx @@ -1,36 +1,91 @@ import { foldersAtom, patchModel } from '@yaakapp-internal/models'; import { useAtomValue } from 'jotai'; +import { useMemo, useState } from 'react'; +import { useAuthTab } from '../hooks/useAuthTab'; +import { useHeadersTab } from '../hooks/useHeadersTab'; +import { useInheritedHeaders } from '../hooks/useInheritedHeaders'; import { Input } from './core/Input'; import { VStack } from './core/Stacks'; +import type { TabItem } from './core/Tabs/Tabs'; +import { TabContent, Tabs } from './core/Tabs/Tabs'; +import { HeadersEditor } from './HeadersEditor'; +import { HttpAuthenticationEditor } from './HttpAuthenticationEditor'; import { MarkdownEditor } from './MarkdownEditor'; interface Props { folderId: string | null; + tab?: FolderSettingsTab; } -export function FolderSettingsDialog({ folderId }: Props) { +const TAB_AUTH = 'auth'; +const TAB_HEADERS = 'headers'; +const TAB_GENERAL = 'general'; + +export type FolderSettingsTab = typeof TAB_AUTH | typeof TAB_HEADERS | typeof TAB_GENERAL; + +export function FolderSettingsDialog({ folderId, tab }: Props) { const folders = useAtomValue(foldersAtom); - const folder = folders.find((f) => f.id === folderId); + const folder = folders.find((f) => f.id === folderId) ?? null; + const [activeTab, setActiveTab] = useState(tab ?? TAB_GENERAL); + const authTab = useAuthTab(TAB_AUTH, folder); + const headersTab = useHeadersTab(TAB_HEADERS, folder); + const inheritedHeaders = useInheritedHeaders(folder); + + const tabs = useMemo(() => { + if (folder == null) return []; + + return [ + { + value: TAB_GENERAL, + label: 'General', + }, + ...authTab, + ...headersTab, + ]; + }, [authTab, folder, headersTab]); if (folder == null) return null; return ( - - patchModel(folder, { name })} - stateKey={`name.${folder.id}`} - /> - - patchModel(folder, { description })} - /> - + + + + + + + patchModel(folder, { name })} + stateKey={`name.${folder.id}`} + /> + + patchModel(folder, { description })} + /> + + + + patchModel(folder, { headers })} + stateKey={`headers.${folder.id}`} + /> + + ); } diff --git a/src-web/components/GitDropdown.tsx b/src-web/components/GitDropdown.tsx index 2d6929492..635507123 100644 --- a/src-web/components/GitDropdown.tsx +++ b/src-web/components/GitDropdown.tsx @@ -343,9 +343,7 @@ function SetupSyncDropdown({ workspaceMeta }: { workspaceMeta: WorkspaceMeta }) color: 'success', label: 'Open Workspace Settings', leftSlot: , - onSelect() { - openWorkspaceSettings.mutate(); - }, + onSelect: openWorkspaceSettings, }, { type: 'separator' }, { diff --git a/src-web/components/GrpcRequestPane.tsx b/src-web/components/GrpcRequestPane.tsx index eb011a31c..6b14bc2a4 100644 --- a/src-web/components/GrpcRequestPane.tsx +++ b/src-web/components/GrpcRequestPane.tsx @@ -1,10 +1,12 @@ -import { type GrpcMetadataEntry, type GrpcRequest, patchModel } from '@yaakapp-internal/models'; +import { type GrpcRequest, type HttpRequestHeader, patchModel } from '@yaakapp-internal/models'; import classNames from 'classnames'; import type { CSSProperties } from 'react'; import React, { useCallback, useMemo, useRef } from 'react'; +import { useAuthTab } from '../hooks/useAuthTab'; import { useContainerSize } from '../hooks/useContainerQuery'; import type { ReflectResponseService } from '../hooks/useGrpc'; -import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication'; +import { useHeadersTab } from '../hooks/useHeadersTab'; +import { useInheritedHeaders } from '../hooks/useInheritedHeaders'; import { useKeyValue } from '../hooks/useKeyValue'; import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey'; import { resolvedModelName } from '../lib/resolvedModelName'; @@ -12,13 +14,13 @@ import { Button } from './core/Button'; import { CountBadge } from './core/CountBadge'; import { Icon } from './core/Icon'; import { IconButton } from './core/IconButton'; -import { PairOrBulkEditor } from './core/PairOrBulkEditor'; import { PlainInput } from './core/PlainInput'; import { RadioDropdown } from './core/RadioDropdown'; import { HStack, VStack } from './core/Stacks'; import type { TabItem } from './core/Tabs/Tabs'; import { TabContent, Tabs } from './core/Tabs/Tabs'; import { GrpcEditor } from './GrpcEditor'; +import { HeadersEditor } from './HeadersEditor'; import { HttpAuthenticationEditor } from './HttpAuthenticationEditor'; import { MarkdownEditor } from './MarkdownEditor'; import { UrlBar } from './UrlBar'; @@ -64,7 +66,9 @@ export function GrpcRequestPane({ onCancel, onSend, }: Props) { - const authentication = useHttpAuthenticationSummaries(); + const authTab = useAuthTab(TAB_AUTH, activeRequest); + const metadataTab = useHeadersTab(TAB_METADATA, activeRequest, 'Metadata'); + const inheritedHeaders = useInheritedHeaders(activeRequest); const { value: activeTabs, set: setActiveTabs } = useKeyValue>({ namespace: 'no_sync', key: 'grpcRequestActiveTabs', @@ -130,42 +134,15 @@ export function GrpcRequestPane({ const tabs: TabItem[] = useMemo( () => [ { value: TAB_MESSAGE, label: 'Message' }, - { - value: TAB_AUTH, - label: 'Auth', - options: { - value: activeRequest.authenticationType, - items: [ - ...authentication.map((a) => ({ - label: a.label || 'UNKNOWN', - shortLabel: a.shortLabel, - value: a.name, - })), - { type: 'separator' }, - { label: 'No Authentication', shortLabel: 'Auth', value: null }, - ], - onChange: async (authenticationType) => { - let authentication: GrpcRequest['authentication'] = activeRequest.authentication; - if (activeRequest.authenticationType !== authenticationType) { - authentication = { - // Reset auth if changing types - }; - } - await patchModel(activeRequest, { - authenticationType, - authentication, - }); - }, - }, - }, - { value: TAB_METADATA, label: 'Metadata' }, + ...metadataTab, + ...authTab, { value: TAB_DESCRIPTION, label: 'Info', rightSlot: activeRequest.description && , }, ], - [activeRequest, authentication], + [activeRequest.description, authTab, metadataTab], ); const activeTab = activeTabs?.[activeRequest.id]; @@ -177,7 +154,7 @@ export function GrpcRequestPane({ ); const handleMetadataChange = useCallback( - (metadata: GrpcMetadataEntry[]) => patchModel(activeRequest, { metadata }), + (metadata: HttpRequestHeader[]) => patchModel(activeRequest, { metadata }), [activeRequest], ); @@ -307,17 +284,15 @@ export function GrpcRequestPane({ /> - + - diff --git a/src-web/components/HeadersEditor.tsx b/src-web/components/HeadersEditor.tsx index 8d8d025d5..5023e46c0 100644 --- a/src-web/components/HeadersEditor.tsx +++ b/src-web/components/HeadersEditor.tsx @@ -5,36 +5,81 @@ import { connections } from '../lib/data/connections'; import { encodings } from '../lib/data/encodings'; import { headerNames } from '../lib/data/headerNames'; import { mimeTypes } from '../lib/data/mimetypes'; +import { Banner } from './core/Banner'; +import { CountBadge } from './core/CountBadge'; import type { GenericCompletionConfig } from './core/Editor/genericCompletion'; import type { InputProps } from './core/Input'; import type { Pair, PairEditorProps } from './core/PairEditor'; +import { ensurePairId, PairEditorRow } from './core/PairEditor'; import { PairOrBulkEditor } from './core/PairOrBulkEditor'; +import { HStack } from './core/Stacks'; type Props = { forceUpdateKey: string; headers: HttpRequestHeader[]; + inheritedHeaders?: HttpRequestHeader[]; stateKey: string; onChange: (headers: HttpRequestHeader[]) => void; + label?: string; }; -export function HeadersEditor({ stateKey, headers, onChange, forceUpdateKey }: Props) { +export function HeadersEditor({ + stateKey, + headers, + inheritedHeaders, + onChange, + forceUpdateKey, +}: Props) { + const validInheritedHeaders = + inheritedHeaders?.filter((pair) => pair.enabled && (pair.name || pair.value)) ?? []; return ( - +
+ {validInheritedHeaders.length > 0 ? ( + +
+ + + Inherited + + +
+ {validInheritedHeaders?.map((pair, i) => ( + {}} + onEnd={() => {}} + onMove={() => {}} + pair={ensurePairId(pair)} + stateKey={null} + /> + ))} +
+
+
+ ) : ( + + )} + +
); } @@ -51,14 +96,14 @@ const headerOptionsMap: Record = { const valueType = (pair: Pair): InputProps['type'] => { const name = pair.name.toLowerCase().trim(); if ( - name.includes('authorization') || - name.includes('api-key') || - name.includes('access-token') || - name.includes('auth') || - name.includes('secret') || - name.includes('token') || - name === 'cookie' || - name === 'set-cookie' + name.includes('authorization') || + name.includes('api-key') || + name.includes('access-token') || + name.includes('auth') || + name.includes('secret') || + name.includes('token') || + name === 'cookie' || + name === 'set-cookie' ) { return 'password'; } else { diff --git a/src-web/components/HttpAuthenticationEditor.tsx b/src-web/components/HttpAuthenticationEditor.tsx index 9ea2422a7..2fbe85fc4 100644 --- a/src-web/components/HttpAuthenticationEditor.tsx +++ b/src-web/components/HttpAuthenticationEditor.tsx @@ -1,34 +1,84 @@ -import type { GrpcRequest, HttpRequest, WebsocketRequest } from '@yaakapp-internal/models'; +import type { + Folder, + GrpcRequest, + HttpRequest, + WebsocketRequest, + Workspace, +} from '@yaakapp-internal/models'; import { patchModel } from '@yaakapp-internal/models'; import React, { useCallback } from 'react'; +import { openFolderSettings } from '../commands/openFolderSettings'; +import { openWorkspaceSettings } from '../commands/openWorkspaceSettings'; import { useHttpAuthenticationConfig } from '../hooks/useHttpAuthenticationConfig'; +import { useInheritedAuthentication } from '../hooks/useInheritedAuthentication'; +import { resolvedModelName } from '../lib/resolvedModelName'; import { Checkbox } from './core/Checkbox'; import type { DropdownItem } from './core/Dropdown'; import { Dropdown } from './core/Dropdown'; import { Icon } from './core/Icon'; import { IconButton } from './core/IconButton'; +import { InlineCode } from './core/InlineCode'; import { HStack } from './core/Stacks'; import { DynamicForm } from './DynamicForm'; import { EmptyStateText } from './EmptyStateText'; interface Props { - request: HttpRequest | GrpcRequest | WebsocketRequest; + model: HttpRequest | GrpcRequest | WebsocketRequest | Folder | Workspace; } -export function HttpAuthenticationEditor({ request }: Props) { +export function HttpAuthenticationEditor({ model }: Props) { + const inheritedAuth = useInheritedAuthentication(model); const authConfig = useHttpAuthenticationConfig( - request.authenticationType, - request.authentication, - request.id, + model.authenticationType, + model.authentication, + model.id, ); const handleChange = useCallback( - (authentication: Record) => patchModel(request, { authentication }), - [request], + async (authentication: Record) => await patchModel(model, { authentication }), + [model], ); - if (authConfig.data == null) { - return No Authentication {request.authenticationType}; + if (model.authenticationType === 'none') { + return No authentication; + } + + if (model.authenticationType != null && authConfig.data == null) { + return ( + + Unknown authentication {authConfig.data} + + ); + } + + if (inheritedAuth == null) { + return Authentication not configured; + } + + if (inheritedAuth.authenticationType === 'none') { + return No authentication; + } + + const wasAuthInherited = inheritedAuth?.id !== model.id; + if (wasAuthInherited) { + const name = resolvedModelName(inheritedAuth); + const cta = inheritedAuth.model === 'workspace' ? 'Workspace' : name; + return ( + +

+ Inherited from{' '} + +

+
+ ); } return ( @@ -36,17 +86,17 @@ export function HttpAuthenticationEditor({ request }: Props) { handleChange({ ...request.authentication, disabled: !disabled })} + checked={!model.authentication.disabled} + onChange={(disabled) => handleChange({ ...model.authentication, disabled: !disabled })} title="Enabled" /> - {authConfig.data.actions && authConfig.data.actions.length > 0 && ( + {authConfig.data?.actions && authConfig.data.actions.length > 0 && ( ({ label: a.label, leftSlot: a.icon ? : null, - onSelect: () => a.call(request), + onSelect: () => a.call(model), }), )} > @@ -55,12 +105,12 @@ export function HttpAuthenticationEditor({ request }: Props) { )} diff --git a/src-web/components/HttpRequestPane.tsx b/src-web/components/HttpRequestPane.tsx index 3506434c4..4b1551f51 100644 --- a/src-web/components/HttpRequestPane.tsx +++ b/src-web/components/HttpRequestPane.tsx @@ -6,13 +6,15 @@ import { atom, useAtomValue } from 'jotai'; import type { CSSProperties } from 'react'; import React, { useCallback, useMemo, useState } from 'react'; import { activeRequestIdAtom } from '../hooks/useActiveRequestId'; +import { allRequestsAtom } from '../hooks/useAllRequests'; +import { useAuthTab } from '../hooks/useAuthTab'; import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse'; -import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication'; +import { useHeadersTab } from '../hooks/useHeadersTab'; import { useImportCurl } from '../hooks/useImportCurl'; +import { useInheritedHeaders } from '../hooks/useInheritedHeaders'; import { useKeyValue } from '../hooks/useKeyValue'; import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse'; import { useRequestEditor, useRequestEditorEvent } from '../hooks/useRequestEditor'; -import { allRequestsAtom } from '../hooks/useAllRequests'; import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey'; import { useSendAnyHttpRequest } from '../hooks/useSendAnyHttpRequest'; import { deepEqualAtom } from '../lib/atoms'; @@ -44,12 +46,12 @@ import { TabContent, Tabs } from './core/Tabs/Tabs'; import { EmptyStateText } from './EmptyStateText'; import { FormMultipartEditor } from './FormMultipartEditor'; import { FormUrlencodedEditor } from './FormUrlencodedEditor'; +import { GraphQLEditor } from './GraphQLEditor'; import { HeadersEditor } from './HeadersEditor'; import { HttpAuthenticationEditor } from './HttpAuthenticationEditor'; import { MarkdownEditor } from './MarkdownEditor'; import { UrlBar } from './UrlBar'; import { UrlParametersEditor } from './UrlParameterEditor'; -import { GraphQLEditor } from './GraphQLEditor'; interface Props { style: CSSProperties; @@ -85,7 +87,9 @@ export function HttpRequestPane({ style, fullHeight, className, activeRequest }: const forceUpdateKey = useRequestUpdateKey(activeRequest.id ?? null); const [{ urlKey }, { focusParamsTab, forceUrlRefresh, forceParamsRefresh }] = useRequestEditor(); const contentType = getContentTypeFromHeaders(activeRequest.headers); - const authentication = useHttpAuthenticationSummaries(); + const authTab = useAuthTab(TAB_AUTH, activeRequest); + const headersTab = useHeadersTab(TAB_HEADERS, activeRequest); + const inheritedHeaders = useInheritedHeaders(activeRequest); const handleContentTypeChange = useCallback( async (contentType: string | null, patch: Partial> = {}) => { @@ -214,42 +218,21 @@ export function HttpRequestPane({ style, fullHeight, className, activeRequest }: rightSlot: , label: 'Params', }, - { - value: TAB_HEADERS, - label: 'Headers', - rightSlot: h.name).length} />, - }, - { - value: TAB_AUTH, - label: 'Auth', - options: { - value: activeRequest.authenticationType, - items: [ - ...authentication.map((a) => ({ - label: a.label || 'UNKNOWN', - shortLabel: a.shortLabel, - value: a.name, - })), - { type: 'separator' }, - { label: 'No Authentication', shortLabel: 'Auth', value: null }, - ], - onChange: async (authenticationType) => { - let authentication: HttpRequest['authentication'] = activeRequest.authentication; - if (activeRequest.authenticationType !== authenticationType) { - authentication = { - // Reset auth if changing types - }; - } - await patchModel(activeRequest, { authenticationType, authentication }); - }, - }, - }, + ...headersTab, + ...authTab, { value: TAB_DESCRIPTION, label: 'Info', }, ], - [activeRequest, authentication, handleContentTypeChange, numParams, urlParameterPairs.length], + [ + activeRequest, + authTab, + handleContentTypeChange, + headersTab, + numParams, + urlParameterPairs.length, + ], ); const { mutate: sendRequest } = useSendAnyHttpRequest(); @@ -372,10 +355,11 @@ export function HttpRequestPane({ style, fullHeight, className, activeRequest }: tabListClassName="mt-2 !mb-1.5" > - + {message} {stack && ( -
+
Stack Trace
{stack}
diff --git a/src-web/components/WebsocketRequestPane.tsx b/src-web/components/WebsocketRequestPane.tsx index 5a390be92..c41c7e507 100644 --- a/src-web/components/WebsocketRequestPane.tsx +++ b/src-web/components/WebsocketRequestPane.tsx @@ -1,4 +1,4 @@ -import type { HttpRequest, WebsocketRequest } from '@yaakapp-internal/models'; +import type { WebsocketRequest } from '@yaakapp-internal/models'; import { patchModel } from '@yaakapp-internal/models'; import type { GenericCompletionOption } from '@yaakapp-internal/plugins'; import { closeWebsocket, connectWebsocket, sendWebsocket } from '@yaakapp-internal/ws'; @@ -9,13 +9,15 @@ import React, { useCallback, useMemo } from 'react'; import { getActiveCookieJar } from '../hooks/useActiveCookieJar'; import { getActiveEnvironment } from '../hooks/useActiveEnvironment'; import { activeRequestIdAtom } from '../hooks/useActiveRequestId'; +import { allRequestsAtom } from '../hooks/useAllRequests'; +import { useAuthTab } from '../hooks/useAuthTab'; import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse'; -import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication'; +import { useHeadersTab } from '../hooks/useHeadersTab'; +import { useInheritedHeaders } from '../hooks/useInheritedHeaders'; import { useKeyValue } from '../hooks/useKeyValue'; import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse'; import { activeWebsocketConnectionAtom } from '../hooks/usePinnedWebsocketConnection'; import { useRequestEditor, useRequestEditorEvent } from '../hooks/useRequestEditor'; -import {allRequestsAtom} from "../hooks/useAllRequests"; import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey'; import { deepEqualAtom } from '../lib/atoms'; import { languageFromContentType } from '../lib/contentType'; @@ -69,7 +71,9 @@ export function WebsocketRequestPane({ style, fullHeight, className, activeReque }); const forceUpdateKey = useRequestUpdateKey(activeRequest.id); const [{ urlKey }, { focusParamsTab, forceUrlRefresh, forceParamsRefresh }] = useRequestEditor(); - const authentication = useHttpAuthenticationSummaries(); + const authTab = useAuthTab(TAB_AUTH, activeRequest); + const headersTab = useHeadersTab(TAB_HEADERS, activeRequest); + const inheritedHeaders = useInheritedHeaders(activeRequest); const { urlParameterPairs, urlParametersKey } = useMemo(() => { const placeholderNames = Array.from(activeRequest.url.matchAll(/\/(:[^/]+)/g)).map( @@ -99,45 +103,14 @@ export function WebsocketRequestPane({ style, fullHeight, className, activeReque rightSlot: , label: 'Params', }, - { - value: TAB_HEADERS, - label: 'Headers', - rightSlot: h.name).length} />, - }, - { - value: TAB_AUTH, - label: 'Auth', - options: { - value: activeRequest.authenticationType, - items: [ - ...authentication.map((a) => ({ - label: a.label || 'UNKNOWN', - shortLabel: a.shortLabel, - value: a.name, - })), - { type: 'separator' }, - { label: 'No Authentication', shortLabel: 'Auth', value: null }, - ], - onChange: async (authenticationType) => { - let authentication: HttpRequest['authentication'] = activeRequest.authentication; - if (activeRequest.authenticationType !== authenticationType) { - authentication = { - // Reset auth if changing types - }; - } - await patchModel(activeRequest, { - authenticationType, - authentication, - }); - }, - }, - }, + ...headersTab, + ...authTab, { value: TAB_DESCRIPTION, label: 'Info', }, ]; - }, [activeRequest, authentication, urlParameterPairs.length]); + }, [authTab, headersTab, urlParameterPairs.length]); const { activeResponse } = usePinnedHttpResponse(activeRequestId); const { mutate: cancelResponse } = useCancelHttpResponse(activeResponse?.id ?? null); @@ -266,10 +239,11 @@ export function WebsocketRequestPane({ style, fullHeight, className, activeReque tabListClassName="mt-2 !mb-1.5" > - + , hotKeyAction: 'workspace_settings.show', - onSelect: () => openWorkspaceSettings.mutate(), + onSelect: openWorkspaceSettings, }, { label: revealInFinderText, diff --git a/src-web/components/WorkspaceSettingsDialog.tsx b/src-web/components/WorkspaceSettingsDialog.tsx index cdde48ed8..9e6a9fea6 100644 --- a/src-web/components/WorkspaceSettingsDialog.tsx +++ b/src-web/components/WorkspaceSettingsDialog.tsx @@ -1,5 +1,9 @@ import { patchModel, workspaceMetasAtom, workspacesAtom } from '@yaakapp-internal/models'; import { useAtomValue } from 'jotai'; +import { useState } from 'react'; +import { useAuthTab } from '../hooks/useAuthTab'; +import { useHeadersTab } from '../hooks/useHeadersTab'; +import { useInheritedHeaders } from '../hooks/useInheritedHeaders'; import { deleteModelWithConfirm } from '../lib/deleteModelWithConfirm'; import { router } from '../lib/router'; import { Banner } from './core/Banner'; @@ -8,6 +12,9 @@ import { InlineCode } from './core/InlineCode'; import { PlainInput } from './core/PlainInput'; import { Separator } from './core/Separator'; import { HStack, VStack } from './core/Stacks'; +import { TabContent, Tabs } from './core/Tabs/Tabs'; +import { HeadersEditor } from './HeadersEditor'; +import { HttpAuthenticationEditor } from './HttpAuthenticationEditor'; import { MarkdownEditor } from './MarkdownEditor'; import { SyncToFilesystemSetting } from './SyncToFilesystemSetting'; import { WorkspaceEncryptionSetting } from './WorkspaceEncryptionSetting'; @@ -15,11 +22,22 @@ import { WorkspaceEncryptionSetting } from './WorkspaceEncryptionSetting'; interface Props { workspaceId: string | null; hide: () => void; + tab?: WorkspaceSettingsTab; } -export function WorkspaceSettingsDialog({ workspaceId, hide }: Props) { +const TAB_AUTH = 'auth'; +const TAB_HEADERS = 'headers'; +const TAB_GENERAL = 'general'; + +export type WorkspaceSettingsTab = typeof TAB_AUTH | typeof TAB_HEADERS | typeof TAB_GENERAL; + +export function WorkspaceSettingsDialog({ workspaceId, hide, tab }: Props) { const workspace = useAtomValue(workspacesAtom).find((w) => w.id === workspaceId); const workspaceMeta = useAtomValue(workspaceMetasAtom).find((m) => m.workspaceId === workspaceId); + const [activeTab, setActiveTab] = useState(tab ?? TAB_GENERAL); + const authTab = useAuthTab(TAB_AUTH, workspace ?? null); + const headersTab = useHeadersTab(TAB_HEADERS, workspace ?? null); + const inheritedHeaders = useInheritedHeaders(workspace ?? null); if (workspace == null) { return ( @@ -37,53 +55,76 @@ export function WorkspaceSettingsDialog({ workspaceId, hide }: Props) { ); return ( - - patchModel(workspace, { name })} - /> + + + + + + patchModel(workspace, { headers })} + stateKey={`headers.${workspace.id}`} + /> + + + + patchModel(workspace, { name })} + /> - patchModel(workspace, { description })} - heightMode="auto" - /> + patchModel(workspace, { description })} + heightMode="auto" + /> - patchModel(workspaceMeta, { settingSyncDir: filePath })} - /> - + patchModel(workspaceMeta, { settingSyncDir: filePath })} + /> + - + - - - {workspaceId} - - + + + {workspaceId} + + + + ); } diff --git a/src-web/components/core/Checkbox.tsx b/src-web/components/core/Checkbox.tsx index 9d453f603..b074c1993 100644 --- a/src-web/components/core/Checkbox.tsx +++ b/src-web/components/core/Checkbox.tsx @@ -52,6 +52,7 @@ export function Checkbox({
diff --git a/src-web/components/core/PairEditor.tsx b/src-web/components/core/PairEditor.tsx index c533bd299..88457b755 100644 --- a/src-web/components/core/PairEditor.tsx +++ b/src-web/components/core/PairEditor.tsx @@ -290,6 +290,8 @@ type PairEditorRowProps = { onFocus?: (pair: PairWithId) => void; onSubmit?: (pair: PairWithId) => void; isLast?: boolean; + disabled?: boolean; + disableDrag?: boolean; index: number; } & Pick< PairEditorProps, @@ -311,21 +313,23 @@ type PairEditorRowProps = { | 'valueValidate' >; -function PairEditorRow({ +export function PairEditorRow({ allowFileValues, allowMultilineValues, className, - forcedEnvironmentId, + disableDrag, + disabled, forceFocusNamePairId, forceFocusValuePairId, forceUpdateKey, + forcedEnvironmentId, index, isLast, nameAutocomplete, - namePlaceholder, - nameValidate, nameAutocompleteFunctions, nameAutocompleteVariables, + namePlaceholder, + nameValidate, onChange, onDelete, onEnd, @@ -461,12 +465,12 @@ function PairEditorRow({ - {!isLast ? ( + {!isLast && !disableDrag ? (
{pair.isFile ? ( - + ) : isLast ? ( // Use PlainInput for last ones because there's a unique bug where clicking below // the Codemirror input focuses it. )} diff --git a/src-web/components/core/RadioDropdown.tsx b/src-web/components/core/RadioDropdown.tsx index 9e03a02d8..4572c2a4d 100644 --- a/src-web/components/core/RadioDropdown.tsx +++ b/src-web/components/core/RadioDropdown.tsx @@ -8,7 +8,7 @@ export type RadioDropdownItem = | { type?: 'default'; label: ReactNode; - shortLabel?: string; + shortLabel?: ReactNode; value: T; rightSlot?: ReactNode; } diff --git a/src-web/components/sidebar/SidebarItemContextMenu.tsx b/src-web/components/sidebar/SidebarItemContextMenu.tsx index 6a79a22ab..ee6a8f3c2 100644 --- a/src-web/components/sidebar/SidebarItemContextMenu.tsx +++ b/src-web/components/sidebar/SidebarItemContextMenu.tsx @@ -1,6 +1,7 @@ import { duplicateModelById, getModel, workspacesAtom } from '@yaakapp-internal/models'; import { useAtomValue } from 'jotai'; import React, { useMemo } from 'react'; +import { openFolderSettings } from '../../commands/openFolderSettings'; import { useCreateDropdownItems } from '../../hooks/useCreateDropdownItems'; import { useHttpRequestActions } from '../../hooks/useHttpRequestActions'; import { useMoveToWorkspace } from '../../hooks/useMoveToWorkspace'; @@ -8,13 +9,11 @@ import { useSendAnyHttpRequest } from '../../hooks/useSendAnyHttpRequest'; import { useSendManyRequests } from '../../hooks/useSendManyRequests'; import { deleteModelWithConfirm } from '../../lib/deleteModelWithConfirm'; -import { showDialog } from '../../lib/dialog'; import { duplicateRequestAndNavigate } from '../../lib/duplicateRequestAndNavigate'; import { renameModelWithPrompt } from '../../lib/renameModelWithPrompt'; import type { DropdownItem } from '../core/Dropdown'; import { ContextMenu } from '../core/Dropdown'; import { Icon } from '../core/Icon'; -import { FolderSettingsDialog } from '../FolderSettingsDialog'; import type { SidebarTreeNode } from './Sidebar'; interface Props { @@ -44,13 +43,7 @@ export function SidebarItemContextMenu({ child, show, close }: Props) { { label: 'Settings', leftSlot: , - onSelect: () => - showDialog({ - id: 'folder-settings', - title: 'Folder Settings', - size: 'md', - render: () => , - }), + onSelect: () => openFolderSettings(child.id), }, { label: 'Duplicate', diff --git a/src-web/hooks/useAuthTab.tsx b/src-web/hooks/useAuthTab.tsx new file mode 100644 index 000000000..c72d70638 --- /dev/null +++ b/src-web/hooks/useAuthTab.tsx @@ -0,0 +1,64 @@ +import type { Folder } from '@yaakapp-internal/models'; +import { patchModel } from '@yaakapp-internal/models'; +import { useMemo } from 'react'; +import { IconTooltip } from '../components/core/IconTooltip'; +import { HStack } from '../components/core/Stacks'; +import type { TabItem } from '../components/core/Tabs/Tabs'; +import { useHttpAuthenticationSummaries } from './useHttpAuthentication'; +import type { AuthenticatedModel} from './useInheritedAuthentication'; +import { useInheritedAuthentication } from './useInheritedAuthentication'; + +export function useAuthTab(tabValue: T, model: AuthenticatedModel | null) { + const authentication = useHttpAuthenticationSummaries(); + const inheritedAuth = useInheritedAuthentication(model); + + return useMemo(() => { + if (model == null) return []; + + const tab: TabItem = { + value: tabValue, + label: 'Auth', + options: { + value: model.authenticationType, + items: [ + ...authentication.map((a) => ({ + label: a.label || 'UNKNOWN', + shortLabel: a.shortLabel, + value: a.name, + })), + { type: 'separator' }, + { + label: 'Inherit from Parent', + shortLabel: + inheritedAuth != null && inheritedAuth.authenticationType != 'none' ? ( + + {authentication.find((a) => a.name === inheritedAuth.authenticationType) + ?.shortLabel ?? 'UNKNOWN'} + + + ) : ( + 'Auth' + ), + value: null, + }, + { label: 'No Auth', shortLabel: 'No Auth', value: 'none' }, + ], + onChange: async (authenticationType) => { + let authentication: Folder['authentication'] = model.authentication; + if (model.authenticationType !== authenticationType) { + authentication = { + // Reset auth if changing types + }; + } + await patchModel(model, { authentication, authenticationType }); + }, + }, + }; + + return [tab]; + }, [authentication, inheritedAuth, model, tabValue]); +} diff --git a/src-web/hooks/useHeadersTab.tsx b/src-web/hooks/useHeadersTab.tsx new file mode 100644 index 000000000..e01f285fe --- /dev/null +++ b/src-web/hooks/useHeadersTab.tsx @@ -0,0 +1,31 @@ +import React, { useMemo } from 'react'; +import { CountBadge } from '../components/core/CountBadge'; +import type { TabItem } from '../components/core/Tabs/Tabs'; +import type { HeaderModel } from './useInheritedHeaders'; +import { useInheritedHeaders } from './useInheritedHeaders'; + +export function useHeadersTab( + tabValue: T, + model: HeaderModel | null, + label?: string, +) { + const inheritedHeaders = useInheritedHeaders(model); + + return useMemo(() => { + if (model == null) return []; + + const allHeaders = [ + ...inheritedHeaders, + ...(model.model === 'grpc_request' ? model.metadata : model.headers), + ]; + const numHeaders = allHeaders.filter((h) => h.name).length; + + const tab: TabItem = { + value: tabValue, + label: label ?? 'Headers', + rightSlot: , + }; + + return [tab]; + }, [inheritedHeaders, label, model, tabValue]); +} diff --git a/src-web/hooks/useHttpAuthenticationConfig.ts b/src-web/hooks/useHttpAuthenticationConfig.ts index a2178b0ef..c37a2d9a2 100644 --- a/src-web/hooks/useHttpAuthenticationConfig.ts +++ b/src-web/hooks/useHttpAuthenticationConfig.ts @@ -1,5 +1,11 @@ import { useQuery } from '@tanstack/react-query'; -import type { GrpcRequest, HttpRequest, WebsocketRequest } from '@yaakapp-internal/models'; +import type { + Folder, + GrpcRequest, + HttpRequest, + WebsocketRequest, + Workspace, +} from '@yaakapp-internal/models'; import { httpResponsesAtom } from '@yaakapp-internal/models'; import type { GetHttpAuthenticationConfigResponse, JsonPrimitive } from '@yaakapp-internal/plugins'; import { useAtomValue } from 'jotai'; @@ -49,13 +55,15 @@ export function useHttpAuthenticationConfig( ...config, actions: config.actions?.map((a, i) => ({ ...a, - call: async ({ id: requestId }: HttpRequest | GrpcRequest | WebsocketRequest) => { + call: async ({ + id: modelId, + }: HttpRequest | GrpcRequest | WebsocketRequest | Folder | Workspace) => { await invokeCmd('cmd_call_http_authentication_action', { pluginRefId: config.pluginRefId, actionIndex: i, authName, values, - requestId, + modelId, }); // Ensure the config is refreshed after the action is done diff --git a/src-web/hooks/useInheritedAuthentication.ts b/src-web/hooks/useInheritedAuthentication.ts new file mode 100644 index 000000000..869234369 --- /dev/null +++ b/src-web/hooks/useInheritedAuthentication.ts @@ -0,0 +1,50 @@ +import type { + Folder, + GrpcRequest, + HttpRequest, + WebsocketRequest, + Workspace, +} from '@yaakapp-internal/models'; +import { foldersAtom, workspacesAtom } from '@yaakapp-internal/models'; +import { atom, useAtomValue } from 'jotai'; + +const ancestorsAtom = atom(function (get) { + return [...get(foldersAtom), ...get(workspacesAtom)]; +}); + +export type AuthenticatedModel = HttpRequest | GrpcRequest | WebsocketRequest | Folder | Workspace; + +export function useInheritedAuthentication( + baseModel: AuthenticatedModel | null, +) { + const parents = useAtomValue(ancestorsAtom); + + if (baseModel == null) return null; + + const next = (child: AuthenticatedModel) => { + // We hit the top + if (child.model === 'workspace') { + return child.authenticationType == null ? null : child; + } + + // Has valid auth + if (child.authenticationType !== null) { + return child; + } + + // Recurse up the tree + const parent = parents.find((p) => { + if (child.folderId) return p.id === child.folderId; + else return p.id === child.workspaceId; + }); + + // Failed to find parent (should never happen) + if (parent == null) { + return null; + } + + return next(parent); + }; + + return next(baseModel); +} diff --git a/src-web/hooks/useInheritedHeaders.ts b/src-web/hooks/useInheritedHeaders.ts new file mode 100644 index 000000000..400463c5f --- /dev/null +++ b/src-web/hooks/useInheritedHeaders.ts @@ -0,0 +1,46 @@ +import type { + Folder, + GrpcRequest, + HttpRequest, + HttpRequestHeader, + WebsocketRequest, + Workspace, +} from '@yaakapp-internal/models'; +import { foldersAtom, workspacesAtom } from '@yaakapp-internal/models'; +import { atom, useAtomValue } from 'jotai'; + +const ancestorsAtom = atom(function (get) { + return [...get(foldersAtom), ...get(workspacesAtom)]; +}); + +export type HeaderModel = HttpRequest | GrpcRequest | WebsocketRequest | Folder | Workspace; + +export function useInheritedHeaders(baseModel: HeaderModel | null) { + const parents = useAtomValue(ancestorsAtom); + + if (baseModel == null) return []; + if (baseModel.model === 'workspace') return []; + + const next = (child: HeaderModel): HttpRequestHeader[] => { + // Short-circuit + if (child.model === 'workspace') { + return []; + } + + // Recurse up the tree + const parent = parents.find((p) => { + if (child.folderId) return p.id === child.folderId; + else return p.id === child.workspaceId; + }); + + // Failed to find parent (should never happen) + if (parent == null) { + return []; + } + + const headers = next(parent); + return [...headers, ...parent.headers]; + }; + + return next(baseModel); +} From 31605881ac7fc1062483833a5f1e05ca564899d9 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 23 May 2025 08:18:29 -0700 Subject: [PATCH 209/996] Render inherited headers in UI --- src-web/components/HeadersEditor.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src-web/components/HeadersEditor.tsx b/src-web/components/HeadersEditor.tsx index 5023e46c0..99fe0aece 100644 --- a/src-web/components/HeadersEditor.tsx +++ b/src-web/components/HeadersEditor.tsx @@ -55,6 +55,10 @@ export function HeadersEditor({ onMove={() => {}} pair={ensurePairId(pair)} stateKey={null} + nameAutocompleteFunctions + nameAutocompleteVariables + valueAutocompleteFunctions + valueAutocompleteVariables /> ))}
From 4d1dda07869288fdf8230bd1c9ec459c863908d0 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 23 May 2025 08:43:52 -0700 Subject: [PATCH 210/996] Fix auth none --- src-tauri/yaak-ws/src/commands.rs | 56 ++++++++++++++++++------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src-tauri/yaak-ws/src/commands.rs b/src-tauri/yaak-ws/src/commands.rs index 11429a451..270ebfae3 100644 --- a/src-tauri/yaak-ws/src/commands.rs +++ b/src-tauri/yaak-ws/src/commands.rs @@ -226,30 +226,38 @@ pub(crate) async fn connect( ); } - if let Some(auth_name) = authentication_type.clone() { - let auth = authentication.clone(); - let plugin_req = CallHttpAuthenticationRequest { - context_id: format!("{:x}", md5::compute(request_id.to_string())), - values: serde_json::from_value(serde_json::to_value(&auth).unwrap()).unwrap(), - method: "POST".to_string(), - url: request.url.clone(), - headers: request - .headers - .clone() - .into_iter() - .map(|h| HttpHeader { - name: h.name, - value: h.value, - }) - .collect(), - }; - let plugin_result = - plugin_manager.call_http_authentication(&window, &auth_name, plugin_req).await?; - for header in plugin_result.set_headers { - headers.insert( - HeaderName::from_str(&header.name).unwrap(), - HeaderValue::from_str(&header.value).unwrap(), - ); + match authentication_type { + None => { + // No authentication found. Not even inherited + } + Some(authentication_type) if authentication_type == "none" => { + // Explicitly no authentication + } + Some(authentication_type) => { + let auth = authentication.clone(); + let plugin_req = CallHttpAuthenticationRequest { + context_id: format!("{:x}", md5::compute(request_id.to_string())), + values: serde_json::from_value(serde_json::to_value(&auth).unwrap()).unwrap(), + method: "POST".to_string(), + url: request.url.clone(), + headers: request + .headers + .clone() + .into_iter() + .map(|h| HttpHeader { + name: h.name, + value: h.value, + }) + .collect(), + }; + let plugin_result = + plugin_manager.call_http_authentication(&window, &authentication_type, plugin_req).await?; + for header in plugin_result.set_headers { + headers.insert( + HeaderName::from_str(&header.name).unwrap(), + HeaderValue::from_str(&header.value).unwrap(), + ); + } } } From 9ec9222216023b605161c95417e606b2beb4e6fd Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 25 May 2025 07:04:40 -0700 Subject: [PATCH 211/996] Fix cookie jar not updating during chained requests https://feedback.yaak.app/p/request-chaining-cookie-not-appear --- src-tauri/src/http_request.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/http_request.rs b/src-tauri/src/http_request.rs index 66f711e20..471f1d1b9 100644 --- a/src-tauri/src/http_request.rs +++ b/src-tauri/src/http_request.rs @@ -153,7 +153,10 @@ pub async fn send_http_request( // Add cookie store if specified let maybe_cookie_manager = match cookie_jar.clone() { - Some(cj) => { + Some(CookieJar { id, .. }) => { + // NOTE: WE need to refetch the cookie jar because a chained request might have + // updated cookies when we rendered the request. + let cj = window.db().get_cookie_jar(&id)?; // HACK: Can't construct Cookie without serde, so we have to do this let cookies = cj .cookies From 9d54e40aa8581242fd18a39e698960dc4bab162c Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 25 May 2025 08:02:36 -0700 Subject: [PATCH 212/996] Add list/get cookie plugin APIs --- .../src/bindings/gen_events.ts | 10 +++- .../src/bindings/gen_models.ts | 6 +-- .../src/plugins/Context.ts | 7 +++ packages/plugin-runtime/src/PluginInstance.ts | 35 +++++++++++-- src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 1 + src-tauri/src/plugin_events.rs | 35 +++++++++++-- .../plugins/auth-oauth2/build/index.js | 18 ++++--- .../plugins/importer-insomnia/build/index.js | 4 +- .../template-function-cookie/build/index.js | 50 +++++++++++++++++++ .../template-function-cookie/package.json | 9 ++++ src-tauri/yaak-models/src/models.rs | 8 +-- src-tauri/yaak-plugins/bindings/gen_events.ts | 10 +++- src-tauri/yaak-plugins/src/events.rs | 31 ++++++++++++ 14 files changed, 199 insertions(+), 26 deletions(-) create mode 100644 src-tauri/vendored/plugins/template-function-cookie/build/index.js create mode 100644 src-tauri/vendored/plugins/template-function-cookie/package.json diff --git a/packages/plugin-runtime-types/src/bindings/gen_events.ts b/packages/plugin-runtime-types/src/bindings/gen_events.ts index ed8dd5463..a67f9f665 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_events.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_events.ts @@ -310,6 +310,10 @@ defaultValue?: string, disabled?: boolean, }; export type GenericCompletionOption = { label: string, detail?: string, info?: string, type?: CompletionOptionType, boost?: number, }; +export type GetCookieValueRequest = { name: string, }; + +export type GetCookieValueResponse = { value: string | null, }; + export type GetHttpAuthenticationConfigRequest = { contextId: string, values: { [key in string]?: JsonPrimitive }, }; export type GetHttpAuthenticationConfigResponse = { args: Array, pluginRefId: string, actions?: Array, }; @@ -346,10 +350,14 @@ export type ImportResponse = { resources: ImportResources, }; export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: PluginWindowContext, payload: InternalEventPayload, }; -export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; +export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "list_cookie_names_request" } & ListCookieNamesRequest | { "type": "list_cookie_names_response" } & ListCookieNamesResponse | { "type": "get_cookie_value_request" } & GetCookieValueRequest | { "type": "get_cookie_value_response" } & GetCookieValueResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; export type JsonPrimitive = string | number | boolean | null; +export type ListCookieNamesRequest = {}; + +export type ListCookieNamesResponse = { names: Array, }; + export type OpenWindowRequest = { url: string, /** * Label for the window. If not provided, a random one will be generated. diff --git a/packages/plugin-runtime-types/src/bindings/gen_models.ts b/packages/plugin-runtime-types/src/bindings/gen_models.ts index 9c981fc95..8d95d78f7 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_models.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_models.ts @@ -4,7 +4,7 @@ export type Environment = { model: "environment", id: string, workspaceId: strin export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id?: string, }; -export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, description: string, name: string, defaultAuthentication: ParentAuthentication, defaultHeaders: Array, sortPriority: number, }; +export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, name: string, sortPriority: number, }; export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; @@ -20,8 +20,6 @@ export type HttpResponseState = "initialized" | "connected" | "closed"; export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, id?: string, }; -export type ParentAuthentication = { authentication: Record, authenticationType: string | null, }; - export type WebsocketRequest = { model: "websocket_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, description: string, headers: Array, message: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; -export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, encryptionKeyChallenge: string | null, defaultAuthentication: ParentAuthentication, defaultHeaders: Array, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; +export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, authentication: Record, authenticationType: string | null, description: string, headers: Array, name: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; diff --git a/packages/plugin-runtime-types/src/plugins/Context.ts b/packages/plugin-runtime-types/src/plugins/Context.ts index f55a38700..fadcf0ba3 100644 --- a/packages/plugin-runtime-types/src/plugins/Context.ts +++ b/packages/plugin-runtime-types/src/plugins/Context.ts @@ -1,8 +1,11 @@ import type { FindHttpResponsesRequest, FindHttpResponsesResponse, + GetCookieValueRequest, + GetCookieValueResponse, GetHttpRequestByIdRequest, GetHttpRequestByIdResponse, + ListCookieNamesResponse, OpenWindowRequest, PromptTextRequest, PromptTextResponse, @@ -38,6 +41,10 @@ export interface Context { }, ): Promise<{ close: () => void }>; }; + cookies: { + listNames(): Promise; + getValue(args: GetCookieValueRequest): Promise; + }; httpRequest: { send(args: SendHttpRequestRequest): Promise; getById(args: GetHttpRequestByIdRequest): Promise; diff --git a/packages/plugin-runtime/src/PluginInstance.ts b/packages/plugin-runtime/src/PluginInstance.ts index 6ebb1e0c1..d77f7e493 100644 --- a/packages/plugin-runtime/src/PluginInstance.ts +++ b/packages/plugin-runtime/src/PluginInstance.ts @@ -1,7 +1,10 @@ -import { PluginWindowContext, TemplateFunctionArg } from '@yaakapp-internal/plugins'; -import type { +import { + GetCookieValueRequest, + GetCookieValueResponse, + ListCookieNamesResponse, + PluginWindowContext, + TemplateFunctionArg, BootRequest, - Context, DeleteKeyValueResponse, FindHttpResponsesResponse, FormInput, @@ -12,16 +15,17 @@ import type { InternalEvent, InternalEventPayload, JsonPrimitive, - PluginDefinition, PromptTextResponse, RenderHttpRequestResponse, SendHttpRequestResponse, TemplateFunction, TemplateRenderResponse, -} from '@yaakapp/api'; +} from '@yaakapp-internal/plugins'; +import { Context, PluginDefinition } from '@yaakapp/api'; import console from 'node:console'; import { readFileSync, type Stats, statSync, watch } from 'node:fs'; import path from 'node:path'; +import Promise from '../../../../../Library/Caches/deno/npm/registry.npmjs.org/any-promise/1.3.0'; // import util from 'node:util'; import { EventChannel } from './EventChannel'; // import { interceptStdout } from './interceptStdout'; @@ -495,6 +499,27 @@ export class PluginInstance { return httpRequest; }, }, + cookies: { + getValue: async (args: GetCookieValueRequest) => { + const payload = { + type: 'get_cookie_value_request', + ...args, + } as const; + const { value } = await this.#sendAndWaitForReply( + event.windowContext, + payload, + ); + return value; + }, + listNames: async () => { + const payload = { type: 'list_cookie_names_request' } as const; + const { names } = await this.#sendAndWaitForReply( + event.windowContext, + payload, + ); + return names; + }, + }, templates: { /** * Invoke Yaak's template engine to render a value. If the value is a nested type diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 400ebedd4..05148f6a2 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -8041,6 +8041,7 @@ name = "yaak-app" version = "0.0.0" dependencies = [ "chrono", + "cookie", "encoding_rs", "eventsource-client", "http", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 1242514f3..03a5596e7 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -40,6 +40,7 @@ openssl-sys = { version = "0.9.105", features = ["vendored"] } # For Ubuntu inst [dependencies] chrono = { version = "0.4.31", features = ["serde"] } +cookie = "0.18.1" encoding_rs = "0.8.35" eventsource-client = { git = "https://github.com/yaakapp/rust-eventsource-client", version = "0.14.0" } http = { version = "1.2.0", default-features = false } diff --git a/src-tauri/src/plugin_events.rs b/src-tauri/src/plugin_events.rs index a535ca2c6..9da132499 100644 --- a/src-tauri/src/plugin_events.rs +++ b/src-tauri/src/plugin_events.rs @@ -6,6 +6,7 @@ use crate::{ workspace_from_window, }; use chrono::Utc; +use cookie::Cookie; use log::warn; use tauri::{AppHandle, Emitter, Manager, Runtime, State}; use tauri_plugin_clipboard_manager::ClipboardExt; @@ -13,10 +14,11 @@ use yaak_models::models::{HttpResponse, Plugin}; use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::UpdateSource; use yaak_plugins::events::{ - Color, DeleteKeyValueResponse, EmptyPayload, FindHttpResponsesResponse, + Color, DeleteKeyValueResponse, EmptyPayload, FindHttpResponsesResponse, GetCookieValueResponse, GetHttpRequestByIdResponse, GetKeyValueResponse, Icon, InternalEvent, InternalEventPayload, - PluginWindowContext, RenderHttpRequestResponse, SendHttpRequestResponse, SetKeyValueResponse, - ShowToastRequest, TemplateRenderResponse, WindowNavigateEvent, + ListCookieNamesResponse, PluginWindowContext, RenderHttpRequestResponse, + SendHttpRequestResponse, SetKeyValueResponse, ShowToastRequest, TemplateRenderResponse, + WindowNavigateEvent, }; use yaak_plugins::manager::PluginManager; use yaak_plugins::plugin_handle::PluginHandle; @@ -269,6 +271,33 @@ pub(crate) async fn handle_plugin_event( let deleted = app_handle.db().delete_plugin_key_value(&name, &req.key).unwrap(); Some(InternalEventPayload::DeleteKeyValueResponse(DeleteKeyValueResponse { deleted })) } + InternalEventPayload::ListCookieNamesRequest(_req) => { + let window = get_window_from_window_context(app_handle, &window_context) + .expect("Failed to find window for listing cookies"); + let names = match cookie_jar_from_window(&window) { + None => Vec::new(), + Some(j) => j + .cookies + .into_iter() + .filter_map(|c| Cookie::parse(c.raw_cookie).ok().map(|c| c.name().to_string())) + .collect(), + }; + Some(InternalEventPayload::ListCookieNamesResponse(ListCookieNamesResponse { names })) + } + InternalEventPayload::GetCookieValueRequest(req) => { + let window = get_window_from_window_context(app_handle, &window_context) + .expect("Failed to find window for listing cookies"); + let value = match cookie_jar_from_window(&window) { + None => None, + Some(j) => j.cookies.into_iter().find_map(|c| match Cookie::parse(c.raw_cookie) { + Ok(c) if c.name().to_string().eq(&req.name) => { + Some(c.value_trimmed().to_string()) + } + _ => None, + }), + }; + Some(InternalEventPayload::GetCookieValueResponse(GetCookieValueResponse { value })) + } _ => None, }; diff --git a/src-tauri/vendored/plugins/auth-oauth2/build/index.js b/src-tauri/vendored/plugins/auth-oauth2/build/index.js index 03a8094d8..bbd055849 100644 --- a/src-tauri/vendored/plugins/auth-oauth2/build/index.js +++ b/src-tauri/vendored/plugins/auth-oauth2/build/index.js @@ -330,7 +330,7 @@ function getImplicit(ctx, contextId, { if (token) { } const authorizationUrl = new URL(`${authorizationUrlRaw ?? ""}`); - authorizationUrl.searchParams.set("response_type", "code"); + authorizationUrl.searchParams.set("response_type", "token"); authorizationUrl.searchParams.set("client_id", clientId); if (redirectUri) authorizationUrl.searchParams.set("redirect_uri", redirectUri); if (scope) authorizationUrl.searchParams.set("scope", scope); @@ -340,22 +340,28 @@ function getImplicit(ctx, contextId, { authorizationUrl.searchParams.set("nonce", String(Math.floor(Math.random() * 9999999999999) + 1)); } const authorizationUrlStr = authorizationUrl.toString(); + let foundAccessToken = false; let { close } = await ctx.window.openUrl({ url: authorizationUrlStr, label: "oauth-authorization-url", + async onClose() { + if (!foundAccessToken) { + reject(new Error("Authorization window closed")); + } + }, async onNavigate({ url: urlStr }) { const url = new URL(urlStr); if (url.searchParams.has("error")) { return reject(Error(`Failed to authorize: ${url.searchParams.get("error")}`)); } - close(); const hash = url.hash.slice(1); const params = new URLSearchParams(hash); - const idToken = params.get("id_token"); - if (idToken) { - params.set("access_token", idToken); - params.delete("id_token"); + const accessToken = params.get("access_token"); + if (!accessToken) { + return; } + foundAccessToken = true; + close(); const response = Object.fromEntries(params); try { resolve(await storeToken(ctx, contextId, response)); diff --git a/src-tauri/vendored/plugins/importer-insomnia/build/index.js b/src-tauri/vendored/plugins/importer-insomnia/build/index.js index 43ad5453f..c23878b04 100644 --- a/src-tauri/vendored/plugins/importer-insomnia/build/index.js +++ b/src-tauri/vendored/plugins/importer-insomnia/build/index.js @@ -7564,7 +7564,7 @@ function importHttpRequest2(r, workspaceId, parentId) { const sortKey = r.meta?.sortKey ?? r.sortKey; let bodyType = null; let body = {}; - if (r.body.mimeType === "application/octet-stream") { + if (r.body?.mimeType === "application/octet-stream") { bodyType = "binary"; body = { filePath: r.body.fileName ?? "" }; } else if (r.body?.mimeType === "application/x-www-form-urlencoded") { @@ -7720,7 +7720,7 @@ function importEnvironment2(e, workspaceId, isParent) { base: isParent ?? e.parentId === workspaceId, model: "environment", name: e.name, - variables: Object.entries(e.data).map(([name, value]) => ({ + variables: Object.entries(e.data ?? {}).map(([name, value]) => ({ enabled: true, name, value: `${value}` diff --git a/src-tauri/vendored/plugins/template-function-cookie/build/index.js b/src-tauri/vendored/plugins/template-function-cookie/build/index.js new file mode 100644 index 000000000..c194983ca --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-cookie/build/index.js @@ -0,0 +1,50 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var src_exports = {}; +__export(src_exports, { + plugin: () => plugin +}); +module.exports = __toCommonJS(src_exports); +var plugin = { + templateFunctions: [ + { + name: "cookie.value", + description: "Read the value of a cookie in the jar, by name", + args: [ + { + type: "text", + name: "cookie_name", + label: "Cookie Name" + } + ], + async onRender(ctx, args) { + console.log("COOKIE", args.values.cookie_name); + const cookies = await ctx.cookies.listNames({}); + console.log("COOKIES", cookies); + return ctx.cookies.getValue({ name: String(args.values.cookie_name) }); + } + } + ] +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + plugin +}); diff --git a/src-tauri/vendored/plugins/template-function-cookie/package.json b/src-tauri/vendored/plugins/template-function-cookie/package.json new file mode 100644 index 000000000..1473c0b2f --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-cookie/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/template-function-cookie", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index f6c7f2451..983eba4aa 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -418,10 +418,10 @@ enum CookieExpires { #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[ts(export, export_to = "gen_models.ts")] pub struct Cookie { - raw_cookie: String, - domain: CookieDomain, - expires: CookieExpires, - path: (String, bool), + pub raw_cookie: String, + pub domain: CookieDomain, + pub expires: CookieExpires, + pub path: (String, bool), } #[derive(Debug, Clone, Serialize, Deserialize, Default, TS)] diff --git a/src-tauri/yaak-plugins/bindings/gen_events.ts b/src-tauri/yaak-plugins/bindings/gen_events.ts index ed8dd5463..a67f9f665 100644 --- a/src-tauri/yaak-plugins/bindings/gen_events.ts +++ b/src-tauri/yaak-plugins/bindings/gen_events.ts @@ -310,6 +310,10 @@ defaultValue?: string, disabled?: boolean, }; export type GenericCompletionOption = { label: string, detail?: string, info?: string, type?: CompletionOptionType, boost?: number, }; +export type GetCookieValueRequest = { name: string, }; + +export type GetCookieValueResponse = { value: string | null, }; + export type GetHttpAuthenticationConfigRequest = { contextId: string, values: { [key in string]?: JsonPrimitive }, }; export type GetHttpAuthenticationConfigResponse = { args: Array, pluginRefId: string, actions?: Array, }; @@ -346,10 +350,14 @@ export type ImportResponse = { resources: ImportResources, }; export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: PluginWindowContext, payload: InternalEventPayload, }; -export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; +export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "list_cookie_names_request" } & ListCookieNamesRequest | { "type": "list_cookie_names_response" } & ListCookieNamesResponse | { "type": "get_cookie_value_request" } & GetCookieValueRequest | { "type": "get_cookie_value_response" } & GetCookieValueResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; export type JsonPrimitive = string | number | boolean | null; +export type ListCookieNamesRequest = {}; + +export type ListCookieNamesResponse = { names: Array, }; + export type OpenWindowRequest = { url: string, /** * Label for the window. If not provided, a random one will be generated. diff --git a/src-tauri/yaak-plugins/src/events.rs b/src-tauri/yaak-plugins/src/events.rs index ac8f29f8c..5e4ec454e 100644 --- a/src-tauri/yaak-plugins/src/events.rs +++ b/src-tauri/yaak-plugins/src/events.rs @@ -84,6 +84,11 @@ pub enum InternalEventPayload { SendHttpRequestRequest(SendHttpRequestRequest), SendHttpRequestResponse(SendHttpRequestResponse), + ListCookieNamesRequest(ListCookieNamesRequest), + ListCookieNamesResponse(ListCookieNamesResponse), + GetCookieValueRequest(GetCookieValueRequest), + GetCookieValueResponse(GetCookieValueResponse), + // Request Actions GetHttpRequestActionsRequest(EmptyPayload), GetHttpRequestActionsResponse(GetHttpRequestActionsResponse), @@ -231,6 +236,32 @@ pub struct SendHttpRequestResponse { pub http_response: HttpResponse, } +#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] +#[serde(default)] +#[ts(export, type = "{}", export_to = "gen_events.ts")] +pub struct ListCookieNamesRequest {} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] +#[serde(default, rename_all = "camelCase")] +#[ts(export, export_to = "gen_events.ts")] +pub struct ListCookieNamesResponse { + pub names: Vec, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] +#[serde(default, rename_all = "camelCase")] +#[ts(export, export_to = "gen_events.ts")] +pub struct GetCookieValueRequest { + pub name: String, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] +#[serde(default, rename_all = "camelCase")] +#[ts(export, export_to = "gen_events.ts")] +pub struct GetCookieValueResponse { + pub value: Option, +} + #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] From 4609c95ad53a9285fa753af6fa0feded457d57c3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 25 May 2025 08:03:29 -0700 Subject: [PATCH 213/996] Fix env editor switching (#216) --- src-web/components/core/PairEditor.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src-web/components/core/PairEditor.tsx b/src-web/components/core/PairEditor.tsx index 88457b755..7cbf09308 100644 --- a/src-web/components/core/PairEditor.tsx +++ b/src-web/components/core/PairEditor.tsx @@ -12,6 +12,7 @@ import { } from 'react'; import type { XYCoord } from 'react-dnd'; import { useDrag, useDrop } from 'react-dnd'; +import { useRandomKey } from '../../hooks/useRandomKey'; import { useToggle } from '../../hooks/useToggle'; import { languageFromContentType } from '../../lib/contentType'; import { showDialog } from '../../lib/dialog'; @@ -107,6 +108,9 @@ export const PairEditor = forwardRef(function Pa const [hoveredIndex, setHoveredIndex] = useState(null); const [pairs, setPairs] = useState([]); const [showAll, toggleShowAll] = useToggle(false); + // NOTE: Use local force update key because we trigger an effect on forceUpdateKey change. If + // we simply pass forceUpdateKey to the editor, the data set by useEffect will be stale. + const [localForceUpdateKey, regenerateLocalForceUpdateKey] = useRandomKey(); useImperativeHandle( ref, @@ -136,6 +140,7 @@ export const PairEditor = forwardRef(function Pa } setPairs(newPairs); + regenerateLocalForceUpdateKey(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [forceUpdateKey]); @@ -240,7 +245,7 @@ export const PairEditor = forwardRef(function Pa forcedEnvironmentId={forcedEnvironmentId} forceFocusNamePairId={forceFocusNamePairId} forceFocusValuePairId={forceFocusValuePairId} - forceUpdateKey={forceUpdateKey} + forceUpdateKey={localForceUpdateKey} index={i} isLast={isLast} nameAutocomplete={nameAutocomplete} From 0a932798a08e8728994d69e665ad2b2d04642a6d Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 25 May 2025 20:25:13 -0700 Subject: [PATCH 214/996] API support for added template functions (eg. cookies) --- packages/plugin-runtime-types/package.json | 2 +- .../src/bindings/gen_events.ts | 42 ++++++++-- .../template-function-cookie/build/index.js | 3 - .../template-function-encode/build/index.js | 49 +++++++++++ .../template-function-encode/package.json | 9 ++ .../template-function-hash/build/index.js | 84 +++++++++++++++---- .../template-function-regex/build/index.js | 52 ++++++++++++ .../template-function-regex/package.json | 9 ++ src-tauri/yaak-models/src/models.rs | 4 +- src-tauri/yaak-plugins/bindings/gen_events.ts | 42 ++++++++-- src-tauri/yaak-plugins/src/events.rs | 4 + src-web/components/DynamicForm.tsx | 6 ++ src-web/components/core/Input.tsx | 19 +++-- src-web/components/core/Select.tsx | 4 +- 14 files changed, 284 insertions(+), 45 deletions(-) create mode 100644 src-tauri/vendored/plugins/template-function-encode/build/index.js create mode 100644 src-tauri/vendored/plugins/template-function-encode/package.json create mode 100644 src-tauri/vendored/plugins/template-function-regex/build/index.js create mode 100644 src-tauri/vendored/plugins/template-function-regex/package.json diff --git a/packages/plugin-runtime-types/package.json b/packages/plugin-runtime-types/package.json index 7c6fb290d..510732ecf 100644 --- a/packages/plugin-runtime-types/package.json +++ b/packages/plugin-runtime-types/package.json @@ -1,6 +1,6 @@ { "name": "@yaakapp/api", - "version": "0.5.3", + "version": "0.6.0", "main": "lib/index.js", "typings": "./lib/index.d.ts", "files": [ diff --git a/packages/plugin-runtime-types/src/bindings/gen_events.ts b/packages/plugin-runtime-types/src/bindings/gen_events.ts index a67f9f665..4d762f6e0 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_events.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_events.ts @@ -104,7 +104,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputCheckbox = { /** @@ -131,7 +135,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputEditor = { /** @@ -170,7 +178,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputFile = { /** @@ -205,7 +217,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputHttpRequest = { /** @@ -232,7 +248,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputMarkdown = { content: string, hidden?: boolean, }; @@ -265,7 +285,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputSelectOption = { label: string, value: string, }; @@ -306,7 +330,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type GenericCompletionOption = { label: string, detail?: string, info?: string, type?: CompletionOptionType, boost?: number, }; diff --git a/src-tauri/vendored/plugins/template-function-cookie/build/index.js b/src-tauri/vendored/plugins/template-function-cookie/build/index.js index c194983ca..42696360e 100644 --- a/src-tauri/vendored/plugins/template-function-cookie/build/index.js +++ b/src-tauri/vendored/plugins/template-function-cookie/build/index.js @@ -36,9 +36,6 @@ var plugin = { } ], async onRender(ctx, args) { - console.log("COOKIE", args.values.cookie_name); - const cookies = await ctx.cookies.listNames({}); - console.log("COOKIES", cookies); return ctx.cookies.getValue({ name: String(args.values.cookie_name) }); } } diff --git a/src-tauri/vendored/plugins/template-function-encode/build/index.js b/src-tauri/vendored/plugins/template-function-encode/build/index.js new file mode 100644 index 000000000..28195b7c2 --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-encode/build/index.js @@ -0,0 +1,49 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var src_exports = {}; +__export(src_exports, { + plugin: () => plugin +}); +module.exports = __toCommonJS(src_exports); +var plugin = { + templateFunctions: [ + { + name: "base64.encode", + description: "Encode a value to base64", + args: [{ label: "Plain Text", type: "text", name: "value", multiLine: true }], + async onRender(_ctx, args) { + return Buffer.from(args.values.value ?? "").toString("base64"); + } + }, + { + name: "base64.decode", + description: "Decode a value from base64", + args: [{ label: "Encoded Value", type: "text", name: "value", multiLine: true }], + async onRender(_ctx, args) { + return Buffer.from(args.values.value ?? "", "base64").toString("utf-8"); + } + } + ] +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + plugin +}); diff --git a/src-tauri/vendored/plugins/template-function-encode/package.json b/src-tauri/vendored/plugins/template-function-encode/package.json new file mode 100644 index 000000000..4c261fdca --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-encode/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/template-function-encode", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/src-tauri/vendored/plugins/template-function-hash/build/index.js b/src-tauri/vendored/plugins/template-function-hash/build/index.js index 7fe4f9afa..3f83a694d 100644 --- a/src-tauri/vendored/plugins/template-function-hash/build/index.js +++ b/src-tauri/vendored/plugins/template-function-hash/build/index.js @@ -25,24 +25,76 @@ __export(src_exports, { module.exports = __toCommonJS(src_exports); var import_node_crypto = require("node:crypto"); var algorithms = ["md5", "sha1", "sha256", "sha512"]; -var plugin = { - templateFunctions: algorithms.map((algorithm) => ({ - name: `hash.${algorithm}`, - description: "Hash a value to its hexidecimal representation", - args: [ - { - name: "input", - label: "Input", - placeholder: "input text", - type: "text" - } - ], - async onRender(_ctx, args) { - if (!args.values.input) return ""; - return (0, import_node_crypto.createHash)(algorithm).update(args.values.input, "utf-8").digest("hex"); +var encodings = ["base64", "hex"]; +var hashFunctions = algorithms.map((algorithm) => ({ + name: `hash.${algorithm}`, + description: "Hash a value to its hexidecimal representation", + args: [ + { + type: "text", + name: "input", + label: "Input", + placeholder: "input text", + multiLine: true + }, + { + type: "select", + name: "encoding", + label: "Encoding", + defaultValue: "base64", + options: encodings.map((encoding) => ({ + label: capitalize(encoding), + value: encoding + })) + } + ], + async onRender(_ctx, args) { + const input = String(args.values.input); + const encoding = String(args.values.encoding); + return (0, import_node_crypto.createHash)(algorithm).update(input, "utf-8").digest(encoding); + } +})); +var hmacFunctions = algorithms.map((algorithm) => ({ + name: `hmac.${algorithm}`, + description: "Compute the HMAC of a value", + args: [ + { + type: "text", + name: "input", + label: "Input", + placeholder: "input text", + multiLine: true + }, + { + type: "text", + name: "key", + label: "Key", + password: true + }, + { + type: "select", + name: "encoding", + label: "Encoding", + defaultValue: "base64", + options: encodings.map((encoding) => ({ + value: encoding, + label: capitalize(encoding) + })) } - })) + ], + async onRender(_ctx, args) { + const input = String(args.values.input); + const key = String(args.values.key); + const encoding = String(args.values.encoding); + return (0, import_node_crypto.createHmac)(algorithm, key, {}).update(input).digest(encoding); + } +})); +var plugin = { + templateFunctions: [...hashFunctions, ...hmacFunctions] }; +function capitalize(str) { + return str.charAt(0).toUpperCase() + str.slice(1); +} // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { plugin diff --git a/src-tauri/vendored/plugins/template-function-regex/build/index.js b/src-tauri/vendored/plugins/template-function-regex/build/index.js new file mode 100644 index 000000000..f45972301 --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-regex/build/index.js @@ -0,0 +1,52 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var src_exports = {}; +__export(src_exports, { + plugin: () => plugin +}); +module.exports = __toCommonJS(src_exports); +var plugin = { + templateFunctions: [{ + name: "regex.match", + description: "Extract", + args: [ + { + type: "text", + name: "regex", + label: "Regular Expression", + placeholder: "^w+=(?w*)$", + defaultValue: "^(.*)$", + description: "A JavaScript regular expression, evaluated using the Node.js RegExp engine. Capture groups or named groups can be used to extract values." + }, + { type: "text", name: "input", label: "Input Text", multiLine: true } + ], + async onRender(_ctx, args) { + if (!args.values.regex) return ""; + const regex = new RegExp(String(args.values.regex)); + const match = args.values.input?.match(regex); + return match?.groups ? Object.values(match.groups)[0] ?? "" : match?.[1] ?? match?.[0] ?? ""; + } + }] +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + plugin +}); diff --git a/src-tauri/vendored/plugins/template-function-regex/package.json b/src-tauri/vendored/plugins/template-function-regex/package.json new file mode 100644 index 000000000..de67316b1 --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-regex/package.json @@ -0,0 +1,9 @@ +{ + "name": "@yaakapp/template-function-regex", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + } +} diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index 983eba4aa..d9917ea4f 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -401,7 +401,7 @@ impl UpsertModelInfo for WorkspaceMeta { #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[ts(export, export_to = "gen_models.ts")] -enum CookieDomain { +pub enum CookieDomain { HostOnly(String), Suffix(String), NotPresent, @@ -410,7 +410,7 @@ enum CookieDomain { #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[ts(export, export_to = "gen_models.ts")] -enum CookieExpires { +pub enum CookieExpires { AtUtc(String), SessionEnd, } diff --git a/src-tauri/yaak-plugins/bindings/gen_events.ts b/src-tauri/yaak-plugins/bindings/gen_events.ts index a67f9f665..4d762f6e0 100644 --- a/src-tauri/yaak-plugins/bindings/gen_events.ts +++ b/src-tauri/yaak-plugins/bindings/gen_events.ts @@ -104,7 +104,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputCheckbox = { /** @@ -131,7 +135,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputEditor = { /** @@ -170,7 +178,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputFile = { /** @@ -205,7 +217,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputHttpRequest = { /** @@ -232,7 +248,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputMarkdown = { content: string, hidden?: boolean, }; @@ -265,7 +285,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type FormInputSelectOption = { label: string, value: string, }; @@ -306,7 +330,11 @@ hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, }; +defaultValue?: string, disabled?: boolean, +/** + * Longer description of the input, likely shown in a tooltip + */ +description?: string, }; export type GenericCompletionOption = { label: string, detail?: string, info?: string, type?: CompletionOptionType, boost?: number, }; diff --git a/src-tauri/yaak-plugins/src/events.rs b/src-tauri/yaak-plugins/src/events.rs index 5e4ec454e..faebabe55 100644 --- a/src-tauri/yaak-plugins/src/events.rs +++ b/src-tauri/yaak-plugins/src/events.rs @@ -594,6 +594,10 @@ pub struct FormInputBase { #[ts(optional)] pub disabled: Option, + + /// Longer description of the input, likely shown in a tooltip + #[ts(optional)] + pub description: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] diff --git a/src-web/components/DynamicForm.tsx b/src-web/components/DynamicForm.tsx index ce4817b53..4db425ada 100644 --- a/src-web/components/DynamicForm.tsx +++ b/src-web/components/DynamicForm.tsx @@ -237,6 +237,7 @@ function TextArg({ defaultValue={value === DYNAMIC_FORM_NULL_ARG ? arg.defaultValue : value} required={!arg.optional} disabled={arg.disabled} + help={arg.description} type={arg.password ? 'password' : 'text'} label={arg.label ?? arg.name} size={INPUT_SIZE} @@ -278,6 +279,7 @@ function EditorArg({ htmlFor={id} required={!arg.optional} visuallyHidden={arg.hideLabel} + help={arg.description} tags={arg.language ? [capitalize(arg.language)] : undefined} > {arg.label} @@ -319,6 +321,7 @@ function SelectArg({ patchModel(folder, { name })} stateKey={`name.${folder.id}`} /> - patchModel(folder, { description })} diff --git a/src-web/components/HttpAuthenticationEditor.tsx b/src-web/components/HttpAuthenticationEditor.tsx index 2fbe85fc4..b42fb50db 100644 --- a/src-web/components/HttpAuthenticationEditor.tsx +++ b/src-web/components/HttpAuthenticationEditor.tsx @@ -18,6 +18,7 @@ import { Dropdown } from './core/Dropdown'; import { Icon } from './core/Icon'; import { IconButton } from './core/IconButton'; import { InlineCode } from './core/InlineCode'; +import { Link } from './core/Link'; import { HStack } from './core/Stacks'; import { DynamicForm } from './DynamicForm'; import { EmptyStateText } from './EmptyStateText'; @@ -52,7 +53,20 @@ export function HttpAuthenticationEditor({ model }: Props) { } if (inheritedAuth == null) { - return Authentication not configured; + if (model.model === 'workspace' || model.model === 'folder') { + return ( + +

+ Apply auth to all requests in {resolvedModelName(model)} +

+ + Documentation + +
+ ); + } else { + return Authentication not configured; + } } if (inheritedAuth.authenticationType === 'none') { diff --git a/src-web/components/WorkspaceSettingsDialog.tsx b/src-web/components/WorkspaceSettingsDialog.tsx index 9e6a9fea6..feb9f0efa 100644 --- a/src-web/components/WorkspaceSettingsDialog.tsx +++ b/src-web/components/WorkspaceSettingsDialog.tsx @@ -26,15 +26,22 @@ interface Props { } const TAB_AUTH = 'auth'; +const TAB_DESCRIPTION = 'description'; const TAB_HEADERS = 'headers'; const TAB_GENERAL = 'general'; -export type WorkspaceSettingsTab = typeof TAB_AUTH | typeof TAB_HEADERS | typeof TAB_GENERAL; +export type WorkspaceSettingsTab = + | typeof TAB_AUTH + | typeof TAB_HEADERS + | typeof TAB_GENERAL + | typeof TAB_DESCRIPTION; + +const DEFAULT_TAB: WorkspaceSettingsTab = TAB_DESCRIPTION; export function WorkspaceSettingsDialog({ workspaceId, hide, tab }: Props) { const workspace = useAtomValue(workspacesAtom).find((w) => w.id === workspaceId); const workspaceMeta = useAtomValue(workspaceMetasAtom).find((m) => m.workspaceId === workspaceId); - const [activeTab, setActiveTab] = useState(tab ?? TAB_GENERAL); + const [activeTab, setActiveTab] = useState(tab ?? DEFAULT_TAB); const authTab = useAuthTab(TAB_AUTH, workspace ?? null); const headersTab = useHeadersTab(TAB_HEADERS, workspace ?? null); const inheritedHeaders = useInheritedHeaders(workspace ?? null); @@ -61,7 +68,15 @@ export function WorkspaceSettingsDialog({ workspaceId, hide, tab }: Props) { label="Folder Settings" className="px-1.5 pb-2" addBorders - tabs={[{ value: TAB_GENERAL, label: 'General' }, ...authTab, ...headersTab]} + tabs={[ + { value: TAB_DESCRIPTION, label: 'Description' }, + { + value: TAB_GENERAL, + label: 'General', + }, + ...authTab, + ...headersTab, + ]} > @@ -75,7 +90,7 @@ export function WorkspaceSettingsDialog({ workspaceId, hide, tab }: Props) { stateKey={`headers.${workspace.id}`} /> - + patchModel(workspace, { description })} heightMode="auto" /> - + + + + Date: Wed, 28 May 2025 13:07:29 -0700 Subject: [PATCH 222/996] UUID, json/x path --- package-lock.json | 108 +++++++++++++++++++- plugins/filter-jsonpath/package.json | 2 +- plugins/template-function-json/package.json | 15 +++ plugins/template-function-json/src/index.ts | 45 ++++++++ plugins/template-function-uuid/package.json | 12 +++ plugins/template-function-uuid/src/index.ts | 76 ++++++++++++++ plugins/template-function-xml/package.json | 13 +++ plugins/template-function-xml/src/index.ts | 29 ++++++ 8 files changed, 298 insertions(+), 2 deletions(-) create mode 100755 plugins/template-function-json/package.json create mode 100755 plugins/template-function-json/src/index.ts create mode 100644 plugins/template-function-uuid/package.json create mode 100644 plugins/template-function-uuid/src/index.ts create mode 100755 plugins/template-function-xml/package.json create mode 100755 plugins/template-function-xml/src/index.ts diff --git a/package-lock.json b/package-lock.json index f8ee1c25c..bfb1d1b47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1070,6 +1070,10 @@ "resolved": "plugins/template-function-hash", "link": true }, + "node_modules/@yaakapp/template-function-json": { + "resolved": "plugins/template-function-json", + "link": true + }, "node_modules/@yaakapp/template-function-prompt": { "resolved": "plugins/template-function-prompt", "link": true @@ -1086,6 +1090,14 @@ "resolved": "plugins/template-function-response", "link": true }, + "node_modules/@yaakapp/template-function-uuid": { + "resolved": "plugins/template-function-uuid", + "link": true + }, + "node_modules/@yaakapp/template-function-xml": { + "resolved": "plugins/template-function-xml", + "link": true + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -7152,12 +7164,30 @@ "name": "@yaakapp/filter-jsonpath", "version": "0.0.1", "dependencies": { - "jsonpath-plus": "^9.0.0" + "jsonpath-plus": "^10.3.0" }, "devDependencies": { "@types/jsonpath": "^0.2.4" } }, + "plugins/filter-jsonpath/node_modules/jsonpath-plus": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz", + "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==", + "license": "MIT", + "dependencies": { + "@jsep-plugin/assignment": "^1.3.0", + "@jsep-plugin/regex": "^1.0.4", + "jsep": "^1.4.0" + }, + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, "plugins/filter-xpath": { "name": "@yaakapp/filter-xpath", "version": "0.0.1", @@ -7223,6 +7253,45 @@ "name": "@yaakapp/template-function-hash", "version": "0.0.1" }, + "plugins/template-function-json": { + "name": "@yaakapp/template-function-json", + "version": "0.0.1", + "dependencies": { + "jsonpath-plus": "^10.3.0" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } + }, + "plugins/template-function-json/node_modules/jsonpath-plus": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz", + "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==", + "license": "MIT", + "dependencies": { + "@jsep-plugin/assignment": "^1.3.0", + "@jsep-plugin/regex": "^1.0.4", + "jsep": "^1.4.0" + }, + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "plugins/template-function-jsonpath": { + "name": "@yaakapp/template-function-jsonpath", + "version": "0.0.1", + "extraneous": true, + "dependencies": { + "jsonpath-plus": "^10.3.0" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } + }, "plugins/template-function-prompt": { "name": "@yaakapp/template-function-prompt", "version": "0.0.1" @@ -7251,6 +7320,43 @@ "name": "@yaakapp/template-function-secure", "version": "0.0.1", "extraneous": true + }, + "plugins/template-function-uuid": { + "name": "@yaakapp/template-function-uuid", + "version": "0.0.1", + "dependencies": { + "uuid": "^11.1.0" + } + }, + "plugins/template-function-uuid/node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "plugins/template-function-xml": { + "name": "@yaakapp/template-function-xml", + "version": "0.0.1", + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "xpath": "^0.0.34" + } + }, + "plugins/template-function-xpath": { + "name": "@yaakapp/template-function-xpath", + "version": "0.0.1", + "extraneous": true, + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "xpath": "^0.0.34" + } } } } diff --git a/plugins/filter-jsonpath/package.json b/plugins/filter-jsonpath/package.json index 4d1a1c5a9..028816ac8 100644 --- a/plugins/filter-jsonpath/package.json +++ b/plugins/filter-jsonpath/package.json @@ -7,7 +7,7 @@ "dev": "yaakcli dev ./src/index.js" }, "dependencies": { - "jsonpath-plus": "^9.0.0" + "jsonpath-plus": "^10.3.0" }, "devDependencies": { "@types/jsonpath": "^0.2.4" diff --git a/plugins/template-function-json/package.json b/plugins/template-function-json/package.json new file mode 100755 index 000000000..b18f1a9ad --- /dev/null +++ b/plugins/template-function-json/package.json @@ -0,0 +1,15 @@ +{ + "name": "@yaakapp/template-function-json", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + }, + "dependencies": { + "jsonpath-plus": "^10.3.0" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } +} diff --git a/plugins/template-function-json/src/index.ts b/plugins/template-function-json/src/index.ts new file mode 100755 index 000000000..f2b622e60 --- /dev/null +++ b/plugins/template-function-json/src/index.ts @@ -0,0 +1,45 @@ +import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; +import { JSONPath } from 'jsonpath-plus'; + +export const plugin: PluginDefinition = { + templateFunctions: [ + { + name: 'json.jsonpath', + description: 'Filter JSON-formatted text using JSONPath syntax', + args: [ + { type: 'text', name: 'input', label: 'Input', multiLine: true, placeholder: '{ "foo": "bar" }' }, + { type: 'text', name: 'query', label: 'Query', placeholder: '$..foo' }, + { type: 'checkbox', name: 'formatted', label: 'Format Output' }, + ], + async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { + try { + const parsed = JSON.parse(String(args.values.input)); + const query = String(args.values.query ?? '$').trim(); + let filtered = JSONPath({ path: query, json: parsed }); + if (Array.isArray(filtered)) { + filtered = filtered[0]; + } + + if (args.values.formatted) { + return JSON.stringify(filtered, null, 2); + } else { + return JSON.stringify(filtered); + } + } catch (e) { + return null; + } + }, + }, + { + name: 'json.escape', + description: 'Escape a JSON string, useful when using the output in JSON values', + args: [ + { type: 'text', name: 'input', label: 'Input', multiLine: true, placeholder: 'Hello "World"' }, + ], + async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { + const input = String(args.values.input ?? ''); + return input.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); + }, + }, + ], +}; diff --git a/plugins/template-function-uuid/package.json b/plugins/template-function-uuid/package.json new file mode 100644 index 000000000..4b1538ead --- /dev/null +++ b/plugins/template-function-uuid/package.json @@ -0,0 +1,12 @@ +{ + "name": "@yaakapp/template-function-uuid", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + }, + "dependencies": { + "uuid": "^11.1.0" + } +} diff --git a/plugins/template-function-uuid/src/index.ts b/plugins/template-function-uuid/src/index.ts new file mode 100644 index 000000000..88e3449bf --- /dev/null +++ b/plugins/template-function-uuid/src/index.ts @@ -0,0 +1,76 @@ +import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; +import { v1, v3, v4, v5, v6, v7 } from 'uuid'; + +export const plugin: PluginDefinition = { + templateFunctions: [ + { + name: 'uuid.v1', + description: 'Generate a UUID V1', + args: [], + async onRender(_ctx: Context, _args: CallTemplateFunctionArgs): Promise { + return v1(); + }, + }, + { + name: 'uuid.v3', + description: 'Generate a UUID V3', + args: [ + { type: 'text', name: 'name', label: 'Name' }, + { + type: 'text', + name: 'namespace', + label: 'Namespace UUID', + description: 'A valid UUID to use as the namespace', + placeholder: '24ced880-3bf4-11f0-8329-cd053d577f0e', + }, + ], + async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { + return v3(String(args.values.name), String(args.values.namespace)); + }, + }, + { + name: 'uuid.v4', + description: 'Generate a UUID V4', + args: [], + async onRender(_ctx: Context, _args: CallTemplateFunctionArgs): Promise { + return v4(); + }, + }, + { + name: 'uuid.v5', + description: 'Generate a UUID V5', + args: [ + { type: 'text', name: 'name', label: 'Name' }, + { type: 'text', name: 'namespace', label: 'Namespace' }, + ], + async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { + return v5(String(args.values.name), String(args.values.namespace)); + }, + }, + { + name: 'uuid.v6', + description: 'Generate a UUID V6', + args: [ + { + type: 'text', + name: 'timestamp', + label: 'Timestamp', + optional: true, + description: 'Can be any format that can be parsed by JavaScript new Date(...)', + placeholder: '2025-05-28T11:15:00Z', + }, + ], + async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { + return v6({ msecs: new Date(String(args.values.timestamp)).getTime() }); + }, + }, + { + name: 'uuid.v7', + description: 'Generate a UUID V7', + args: [], + async onRender(_ctx: Context, _args: CallTemplateFunctionArgs): Promise { + return v7(); + }, + }, + ], +}; diff --git a/plugins/template-function-xml/package.json b/plugins/template-function-xml/package.json new file mode 100755 index 000000000..d1274960f --- /dev/null +++ b/plugins/template-function-xml/package.json @@ -0,0 +1,13 @@ +{ + "name": "@yaakapp/template-function-xml", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + }, + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "xpath": "^0.0.34" + } +} diff --git a/plugins/template-function-xml/src/index.ts b/plugins/template-function-xml/src/index.ts new file mode 100755 index 000000000..fdb32b4a8 --- /dev/null +++ b/plugins/template-function-xml/src/index.ts @@ -0,0 +1,29 @@ +import { DOMParser } from '@xmldom/xmldom'; +import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; +import xpath from 'xpath'; + +export const plugin: PluginDefinition = { + templateFunctions: [{ + name: 'xml.xpath', + description: 'Filter XML-formatted text using XPath syntax', + args: [ + { type: 'text', name: 'input', label: 'Input', multiLine: true, placeholder: '' }, + { type: 'text', name: 'query', label: 'Query', placeholder: '//foo' }, + ], + async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { + try { + const doc = new DOMParser().parseFromString(String(args.values.input), 'text/xml'); + let result = xpath.select(String(args.values.query), doc, false); + if (Array.isArray(result)) { + return String(result.map(c => String(c.firstChild))[0]); + } else if (result instanceof Node) { + return String(result.firstChild); + } else { + return String(result); + } + } catch (e) { + return null; + } + }, + }], +}; From 72dd768f55b7605b547e45c8ccdeb6222398f5e3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 28 May 2025 13:08:43 -0700 Subject: [PATCH 223/996] Proper handling of boolean template function args --- .../plugins/filter-jsonpath/build/index.js | 1287 ++- .../plugins/filter-jsonpath/package.json | 2 +- .../template-function-json/build/index.js | 1769 ++++ .../template-function-json/package.json | 15 + .../template-function-uuid/build/index.js | 417 + .../template-function-uuid/package.json | 12 + .../template-function-xml/build/index.js | 8380 +++++++++++++++++ .../template-function-xml/package.json | 13 + src-tauri/yaak-plugins/src/events.rs | 2 +- src-tauri/yaak-plugins/src/manager.rs | 16 +- .../src/native_template_functions.rs | 11 +- .../yaak-plugins/src/template_callback.rs | 2 +- src-tauri/yaak-templates/src/renderer.rs | 42 +- 13 files changed, 11906 insertions(+), 62 deletions(-) create mode 100644 src-tauri/vendored/plugins/template-function-json/build/index.js create mode 100755 src-tauri/vendored/plugins/template-function-json/package.json create mode 100644 src-tauri/vendored/plugins/template-function-uuid/build/index.js create mode 100644 src-tauri/vendored/plugins/template-function-uuid/package.json create mode 100644 src-tauri/vendored/plugins/template-function-xml/build/index.js create mode 100755 src-tauri/vendored/plugins/template-function-xml/package.json diff --git a/src-tauri/vendored/plugins/filter-jsonpath/build/index.js b/src-tauri/vendored/plugins/filter-jsonpath/build/index.js index 81e219a32..703b625b5 100644 --- a/src-tauri/vendored/plugins/filter-jsonpath/build/index.js +++ b/src-tauri/vendored/plugins/filter-jsonpath/build/index.js @@ -30,15 +30,1237 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru // src/index.ts var src_exports = {}; __export(src_exports, { - plugin: () => plugin + plugin: () => plugin2 }); module.exports = __toCommonJS(src_exports); -// ../../node_modules/jsonpath-plus/dist/index-node-esm.js +// node_modules/jsonpath-plus/dist/index-node-esm.js var import_vm = __toESM(require("vm"), 1); -var { - hasOwnProperty: hasOwnProp -} = Object.prototype; +var Hooks = class { + /** + * @callback HookCallback + * @this {*|Jsep} this + * @param {Jsep} env + * @returns: void + */ + /** + * Adds the given callback to the list of callbacks for the given hook. + * + * The callback will be invoked when the hook it is registered for is run. + * + * One callback function can be registered to multiple hooks and the same hook multiple times. + * + * @param {string|object} name The name of the hook, or an object of callbacks keyed by name + * @param {HookCallback|boolean} callback The callback function which is given environment variables. + * @param {?boolean} [first=false] Will add the hook to the top of the list (defaults to the bottom) + * @public + */ + add(name, callback, first) { + if (typeof arguments[0] != "string") { + for (let name2 in arguments[0]) { + this.add(name2, arguments[0][name2], arguments[1]); + } + } else { + (Array.isArray(name) ? name : [name]).forEach(function(name2) { + this[name2] = this[name2] || []; + if (callback) { + this[name2][first ? "unshift" : "push"](callback); + } + }, this); + } + } + /** + * Runs a hook invoking all registered callbacks with the given environment variables. + * + * Callbacks will be invoked synchronously and in the order in which they were registered. + * + * @param {string} name The name of the hook. + * @param {Object} env The environment variables of the hook passed to all callbacks registered. + * @public + */ + run(name, env) { + this[name] = this[name] || []; + this[name].forEach(function(callback) { + callback.call(env && env.context ? env.context : env, env); + }); + } +}; +var Plugins = class { + constructor(jsep2) { + this.jsep = jsep2; + this.registered = {}; + } + /** + * @callback PluginSetup + * @this {Jsep} jsep + * @returns: void + */ + /** + * Adds the given plugin(s) to the registry + * + * @param {object} plugins + * @param {string} plugins.name The name of the plugin + * @param {PluginSetup} plugins.init The init function + * @public + */ + register(...plugins) { + plugins.forEach((plugin3) => { + if (typeof plugin3 !== "object" || !plugin3.name || !plugin3.init) { + throw new Error("Invalid JSEP plugin format"); + } + if (this.registered[plugin3.name]) { + return; + } + plugin3.init(this.jsep); + this.registered[plugin3.name] = plugin3; + }); + } +}; +var Jsep = class _Jsep { + /** + * @returns {string} + */ + static get version() { + return "1.4.0"; + } + /** + * @returns {string} + */ + static toString() { + return "JavaScript Expression Parser (JSEP) v" + _Jsep.version; + } + // ==================== CONFIG ================================ + /** + * @method addUnaryOp + * @param {string} op_name The name of the unary op to add + * @returns {Jsep} + */ + static addUnaryOp(op_name) { + _Jsep.max_unop_len = Math.max(op_name.length, _Jsep.max_unop_len); + _Jsep.unary_ops[op_name] = 1; + return _Jsep; + } + /** + * @method jsep.addBinaryOp + * @param {string} op_name The name of the binary op to add + * @param {number} precedence The precedence of the binary op (can be a float). Higher number = higher precedence + * @param {boolean} [isRightAssociative=false] whether operator is right-associative + * @returns {Jsep} + */ + static addBinaryOp(op_name, precedence, isRightAssociative) { + _Jsep.max_binop_len = Math.max(op_name.length, _Jsep.max_binop_len); + _Jsep.binary_ops[op_name] = precedence; + if (isRightAssociative) { + _Jsep.right_associative.add(op_name); + } else { + _Jsep.right_associative.delete(op_name); + } + return _Jsep; + } + /** + * @method addIdentifierChar + * @param {string} char The additional character to treat as a valid part of an identifier + * @returns {Jsep} + */ + static addIdentifierChar(char) { + _Jsep.additional_identifier_chars.add(char); + return _Jsep; + } + /** + * @method addLiteral + * @param {string} literal_name The name of the literal to add + * @param {*} literal_value The value of the literal + * @returns {Jsep} + */ + static addLiteral(literal_name, literal_value) { + _Jsep.literals[literal_name] = literal_value; + return _Jsep; + } + /** + * @method removeUnaryOp + * @param {string} op_name The name of the unary op to remove + * @returns {Jsep} + */ + static removeUnaryOp(op_name) { + delete _Jsep.unary_ops[op_name]; + if (op_name.length === _Jsep.max_unop_len) { + _Jsep.max_unop_len = _Jsep.getMaxKeyLen(_Jsep.unary_ops); + } + return _Jsep; + } + /** + * @method removeAllUnaryOps + * @returns {Jsep} + */ + static removeAllUnaryOps() { + _Jsep.unary_ops = {}; + _Jsep.max_unop_len = 0; + return _Jsep; + } + /** + * @method removeIdentifierChar + * @param {string} char The additional character to stop treating as a valid part of an identifier + * @returns {Jsep} + */ + static removeIdentifierChar(char) { + _Jsep.additional_identifier_chars.delete(char); + return _Jsep; + } + /** + * @method removeBinaryOp + * @param {string} op_name The name of the binary op to remove + * @returns {Jsep} + */ + static removeBinaryOp(op_name) { + delete _Jsep.binary_ops[op_name]; + if (op_name.length === _Jsep.max_binop_len) { + _Jsep.max_binop_len = _Jsep.getMaxKeyLen(_Jsep.binary_ops); + } + _Jsep.right_associative.delete(op_name); + return _Jsep; + } + /** + * @method removeAllBinaryOps + * @returns {Jsep} + */ + static removeAllBinaryOps() { + _Jsep.binary_ops = {}; + _Jsep.max_binop_len = 0; + return _Jsep; + } + /** + * @method removeLiteral + * @param {string} literal_name The name of the literal to remove + * @returns {Jsep} + */ + static removeLiteral(literal_name) { + delete _Jsep.literals[literal_name]; + return _Jsep; + } + /** + * @method removeAllLiterals + * @returns {Jsep} + */ + static removeAllLiterals() { + _Jsep.literals = {}; + return _Jsep; + } + // ==================== END CONFIG ============================ + /** + * @returns {string} + */ + get char() { + return this.expr.charAt(this.index); + } + /** + * @returns {number} + */ + get code() { + return this.expr.charCodeAt(this.index); + } + /** + * @param {string} expr a string with the passed in express + * @returns Jsep + */ + constructor(expr) { + this.expr = expr; + this.index = 0; + } + /** + * static top-level parser + * @returns {jsep.Expression} + */ + static parse(expr) { + return new _Jsep(expr).parse(); + } + /** + * Get the longest key length of any object + * @param {object} obj + * @returns {number} + */ + static getMaxKeyLen(obj) { + return Math.max(0, ...Object.keys(obj).map((k) => k.length)); + } + /** + * `ch` is a character code in the next three functions + * @param {number} ch + * @returns {boolean} + */ + static isDecimalDigit(ch) { + return ch >= 48 && ch <= 57; + } + /** + * Returns the precedence of a binary operator or `0` if it isn't a binary operator. Can be float. + * @param {string} op_val + * @returns {number} + */ + static binaryPrecedence(op_val) { + return _Jsep.binary_ops[op_val] || 0; + } + /** + * Looks for start of identifier + * @param {number} ch + * @returns {boolean} + */ + static isIdentifierStart(ch) { + return ch >= 65 && ch <= 90 || // A...Z + ch >= 97 && ch <= 122 || // a...z + ch >= 128 && !_Jsep.binary_ops[String.fromCharCode(ch)] || // any non-ASCII that is not an operator + _Jsep.additional_identifier_chars.has(String.fromCharCode(ch)); + } + /** + * @param {number} ch + * @returns {boolean} + */ + static isIdentifierPart(ch) { + return _Jsep.isIdentifierStart(ch) || _Jsep.isDecimalDigit(ch); + } + /** + * throw error at index of the expression + * @param {string} message + * @throws + */ + throwError(message) { + const error = new Error(message + " at character " + this.index); + error.index = this.index; + error.description = message; + throw error; + } + /** + * Run a given hook + * @param {string} name + * @param {jsep.Expression|false} [node] + * @returns {?jsep.Expression} + */ + runHook(name, node) { + if (_Jsep.hooks[name]) { + const env = { + context: this, + node + }; + _Jsep.hooks.run(name, env); + return env.node; + } + return node; + } + /** + * Runs a given hook until one returns a node + * @param {string} name + * @returns {?jsep.Expression} + */ + searchHook(name) { + if (_Jsep.hooks[name]) { + const env = { + context: this + }; + _Jsep.hooks[name].find(function(callback) { + callback.call(env.context, env); + return env.node; + }); + return env.node; + } + } + /** + * Push `index` up to the next non-space character + */ + gobbleSpaces() { + let ch = this.code; + while (ch === _Jsep.SPACE_CODE || ch === _Jsep.TAB_CODE || ch === _Jsep.LF_CODE || ch === _Jsep.CR_CODE) { + ch = this.expr.charCodeAt(++this.index); + } + this.runHook("gobble-spaces"); + } + /** + * Top-level method to parse all expressions and returns compound or single node + * @returns {jsep.Expression} + */ + parse() { + this.runHook("before-all"); + const nodes = this.gobbleExpressions(); + const node = nodes.length === 1 ? nodes[0] : { + type: _Jsep.COMPOUND, + body: nodes + }; + return this.runHook("after-all", node); + } + /** + * top-level parser (but can be reused within as well) + * @param {number} [untilICode] + * @returns {jsep.Expression[]} + */ + gobbleExpressions(untilICode) { + let nodes = [], ch_i, node; + while (this.index < this.expr.length) { + ch_i = this.code; + if (ch_i === _Jsep.SEMCOL_CODE || ch_i === _Jsep.COMMA_CODE) { + this.index++; + } else { + if (node = this.gobbleExpression()) { + nodes.push(node); + } else if (this.index < this.expr.length) { + if (ch_i === untilICode) { + break; + } + this.throwError('Unexpected "' + this.char + '"'); + } + } + } + return nodes; + } + /** + * The main parsing function. + * @returns {?jsep.Expression} + */ + gobbleExpression() { + const node = this.searchHook("gobble-expression") || this.gobbleBinaryExpression(); + this.gobbleSpaces(); + return this.runHook("after-expression", node); + } + /** + * Search for the operation portion of the string (e.g. `+`, `===`) + * Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`) + * and move down from 3 to 2 to 1 character until a matching binary operation is found + * then, return that binary operation + * @returns {string|boolean} + */ + gobbleBinaryOp() { + this.gobbleSpaces(); + let to_check = this.expr.substr(this.index, _Jsep.max_binop_len); + let tc_len = to_check.length; + while (tc_len > 0) { + if (_Jsep.binary_ops.hasOwnProperty(to_check) && (!_Jsep.isIdentifierStart(this.code) || this.index + to_check.length < this.expr.length && !_Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))) { + this.index += tc_len; + return to_check; + } + to_check = to_check.substr(0, --tc_len); + } + return false; + } + /** + * This function is responsible for gobbling an individual expression, + * e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)` + * @returns {?jsep.BinaryExpression} + */ + gobbleBinaryExpression() { + let node, biop, prec, stack, biop_info, left, right, i, cur_biop; + left = this.gobbleToken(); + if (!left) { + return left; + } + biop = this.gobbleBinaryOp(); + if (!biop) { + return left; + } + biop_info = { + value: biop, + prec: _Jsep.binaryPrecedence(biop), + right_a: _Jsep.right_associative.has(biop) + }; + right = this.gobbleToken(); + if (!right) { + this.throwError("Expected expression after " + biop); + } + stack = [left, biop_info, right]; + while (biop = this.gobbleBinaryOp()) { + prec = _Jsep.binaryPrecedence(biop); + if (prec === 0) { + this.index -= biop.length; + break; + } + biop_info = { + value: biop, + prec, + right_a: _Jsep.right_associative.has(biop) + }; + cur_biop = biop; + const comparePrev = (prev) => biop_info.right_a && prev.right_a ? prec > prev.prec : prec <= prev.prec; + while (stack.length > 2 && comparePrev(stack[stack.length - 2])) { + right = stack.pop(); + biop = stack.pop().value; + left = stack.pop(); + node = { + type: _Jsep.BINARY_EXP, + operator: biop, + left, + right + }; + stack.push(node); + } + node = this.gobbleToken(); + if (!node) { + this.throwError("Expected expression after " + cur_biop); + } + stack.push(biop_info, node); + } + i = stack.length - 1; + node = stack[i]; + while (i > 1) { + node = { + type: _Jsep.BINARY_EXP, + operator: stack[i - 1].value, + left: stack[i - 2], + right: node + }; + i -= 2; + } + return node; + } + /** + * An individual part of a binary expression: + * e.g. `foo.bar(baz)`, `1`, `"abc"`, `(a % 2)` (because it's in parenthesis) + * @returns {boolean|jsep.Expression} + */ + gobbleToken() { + let ch, to_check, tc_len, node; + this.gobbleSpaces(); + node = this.searchHook("gobble-token"); + if (node) { + return this.runHook("after-token", node); + } + ch = this.code; + if (_Jsep.isDecimalDigit(ch) || ch === _Jsep.PERIOD_CODE) { + return this.gobbleNumericLiteral(); + } + if (ch === _Jsep.SQUOTE_CODE || ch === _Jsep.DQUOTE_CODE) { + node = this.gobbleStringLiteral(); + } else if (ch === _Jsep.OBRACK_CODE) { + node = this.gobbleArray(); + } else { + to_check = this.expr.substr(this.index, _Jsep.max_unop_len); + tc_len = to_check.length; + while (tc_len > 0) { + if (_Jsep.unary_ops.hasOwnProperty(to_check) && (!_Jsep.isIdentifierStart(this.code) || this.index + to_check.length < this.expr.length && !_Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))) { + this.index += tc_len; + const argument = this.gobbleToken(); + if (!argument) { + this.throwError("missing unaryOp argument"); + } + return this.runHook("after-token", { + type: _Jsep.UNARY_EXP, + operator: to_check, + argument, + prefix: true + }); + } + to_check = to_check.substr(0, --tc_len); + } + if (_Jsep.isIdentifierStart(ch)) { + node = this.gobbleIdentifier(); + if (_Jsep.literals.hasOwnProperty(node.name)) { + node = { + type: _Jsep.LITERAL, + value: _Jsep.literals[node.name], + raw: node.name + }; + } else if (node.name === _Jsep.this_str) { + node = { + type: _Jsep.THIS_EXP + }; + } + } else if (ch === _Jsep.OPAREN_CODE) { + node = this.gobbleGroup(); + } + } + if (!node) { + return this.runHook("after-token", false); + } + node = this.gobbleTokenProperty(node); + return this.runHook("after-token", node); + } + /** + * Gobble properties of of identifiers/strings/arrays/groups. + * e.g. `foo`, `bar.baz`, `foo['bar'].baz` + * It also gobbles function calls: + * e.g. `Math.acos(obj.angle)` + * @param {jsep.Expression} node + * @returns {jsep.Expression} + */ + gobbleTokenProperty(node) { + this.gobbleSpaces(); + let ch = this.code; + while (ch === _Jsep.PERIOD_CODE || ch === _Jsep.OBRACK_CODE || ch === _Jsep.OPAREN_CODE || ch === _Jsep.QUMARK_CODE) { + let optional; + if (ch === _Jsep.QUMARK_CODE) { + if (this.expr.charCodeAt(this.index + 1) !== _Jsep.PERIOD_CODE) { + break; + } + optional = true; + this.index += 2; + this.gobbleSpaces(); + ch = this.code; + } + this.index++; + if (ch === _Jsep.OBRACK_CODE) { + node = { + type: _Jsep.MEMBER_EXP, + computed: true, + object: node, + property: this.gobbleExpression() + }; + if (!node.property) { + this.throwError('Unexpected "' + this.char + '"'); + } + this.gobbleSpaces(); + ch = this.code; + if (ch !== _Jsep.CBRACK_CODE) { + this.throwError("Unclosed ["); + } + this.index++; + } else if (ch === _Jsep.OPAREN_CODE) { + node = { + type: _Jsep.CALL_EXP, + "arguments": this.gobbleArguments(_Jsep.CPAREN_CODE), + callee: node + }; + } else if (ch === _Jsep.PERIOD_CODE || optional) { + if (optional) { + this.index--; + } + this.gobbleSpaces(); + node = { + type: _Jsep.MEMBER_EXP, + computed: false, + object: node, + property: this.gobbleIdentifier() + }; + } + if (optional) { + node.optional = true; + } + this.gobbleSpaces(); + ch = this.code; + } + return node; + } + /** + * Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to + * keep track of everything in the numeric literal and then calling `parseFloat` on that string + * @returns {jsep.Literal} + */ + gobbleNumericLiteral() { + let number = "", ch, chCode; + while (_Jsep.isDecimalDigit(this.code)) { + number += this.expr.charAt(this.index++); + } + if (this.code === _Jsep.PERIOD_CODE) { + number += this.expr.charAt(this.index++); + while (_Jsep.isDecimalDigit(this.code)) { + number += this.expr.charAt(this.index++); + } + } + ch = this.char; + if (ch === "e" || ch === "E") { + number += this.expr.charAt(this.index++); + ch = this.char; + if (ch === "+" || ch === "-") { + number += this.expr.charAt(this.index++); + } + while (_Jsep.isDecimalDigit(this.code)) { + number += this.expr.charAt(this.index++); + } + if (!_Jsep.isDecimalDigit(this.expr.charCodeAt(this.index - 1))) { + this.throwError("Expected exponent (" + number + this.char + ")"); + } + } + chCode = this.code; + if (_Jsep.isIdentifierStart(chCode)) { + this.throwError("Variable names cannot start with a number (" + number + this.char + ")"); + } else if (chCode === _Jsep.PERIOD_CODE || number.length === 1 && number.charCodeAt(0) === _Jsep.PERIOD_CODE) { + this.throwError("Unexpected period"); + } + return { + type: _Jsep.LITERAL, + value: parseFloat(number), + raw: number + }; + } + /** + * Parses a string literal, staring with single or double quotes with basic support for escape codes + * e.g. `"hello world"`, `'this is\nJSEP'` + * @returns {jsep.Literal} + */ + gobbleStringLiteral() { + let str = ""; + const startIndex = this.index; + const quote = this.expr.charAt(this.index++); + let closed = false; + while (this.index < this.expr.length) { + let ch = this.expr.charAt(this.index++); + if (ch === quote) { + closed = true; + break; + } else if (ch === "\\") { + ch = this.expr.charAt(this.index++); + switch (ch) { + case "n": + str += "\n"; + break; + case "r": + str += "\r"; + break; + case "t": + str += " "; + break; + case "b": + str += "\b"; + break; + case "f": + str += "\f"; + break; + case "v": + str += "\v"; + break; + default: + str += ch; + } + } else { + str += ch; + } + } + if (!closed) { + this.throwError('Unclosed quote after "' + str + '"'); + } + return { + type: _Jsep.LITERAL, + value: str, + raw: this.expr.substring(startIndex, this.index) + }; + } + /** + * Gobbles only identifiers + * e.g.: `foo`, `_value`, `$x1` + * Also, this function checks if that identifier is a literal: + * (e.g. `true`, `false`, `null`) or `this` + * @returns {jsep.Identifier} + */ + gobbleIdentifier() { + let ch = this.code, start = this.index; + if (_Jsep.isIdentifierStart(ch)) { + this.index++; + } else { + this.throwError("Unexpected " + this.char); + } + while (this.index < this.expr.length) { + ch = this.code; + if (_Jsep.isIdentifierPart(ch)) { + this.index++; + } else { + break; + } + } + return { + type: _Jsep.IDENTIFIER, + name: this.expr.slice(start, this.index) + }; + } + /** + * Gobbles a list of arguments within the context of a function call + * or array literal. This function also assumes that the opening character + * `(` or `[` has already been gobbled, and gobbles expressions and commas + * until the terminator character `)` or `]` is encountered. + * e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]` + * @param {number} termination + * @returns {jsep.Expression[]} + */ + gobbleArguments(termination) { + const args = []; + let closed = false; + let separator_count = 0; + while (this.index < this.expr.length) { + this.gobbleSpaces(); + let ch_i = this.code; + if (ch_i === termination) { + closed = true; + this.index++; + if (termination === _Jsep.CPAREN_CODE && separator_count && separator_count >= args.length) { + this.throwError("Unexpected token " + String.fromCharCode(termination)); + } + break; + } else if (ch_i === _Jsep.COMMA_CODE) { + this.index++; + separator_count++; + if (separator_count !== args.length) { + if (termination === _Jsep.CPAREN_CODE) { + this.throwError("Unexpected token ,"); + } else if (termination === _Jsep.CBRACK_CODE) { + for (let arg = args.length; arg < separator_count; arg++) { + args.push(null); + } + } + } + } else if (args.length !== separator_count && separator_count !== 0) { + this.throwError("Expected comma"); + } else { + const node = this.gobbleExpression(); + if (!node || node.type === _Jsep.COMPOUND) { + this.throwError("Expected comma"); + } + args.push(node); + } + } + if (!closed) { + this.throwError("Expected " + String.fromCharCode(termination)); + } + return args; + } + /** + * Responsible for parsing a group of things within parentheses `()` + * that have no identifier in front (so not a function call) + * This function assumes that it needs to gobble the opening parenthesis + * and then tries to gobble everything within that parenthesis, assuming + * that the next thing it should see is the close parenthesis. If not, + * then the expression probably doesn't have a `)` + * @returns {boolean|jsep.Expression} + */ + gobbleGroup() { + this.index++; + let nodes = this.gobbleExpressions(_Jsep.CPAREN_CODE); + if (this.code === _Jsep.CPAREN_CODE) { + this.index++; + if (nodes.length === 1) { + return nodes[0]; + } else if (!nodes.length) { + return false; + } else { + return { + type: _Jsep.SEQUENCE_EXP, + expressions: nodes + }; + } + } else { + this.throwError("Unclosed ("); + } + } + /** + * Responsible for parsing Array literals `[1, 2, 3]` + * This function assumes that it needs to gobble the opening bracket + * and then tries to gobble the expressions as arguments. + * @returns {jsep.ArrayExpression} + */ + gobbleArray() { + this.index++; + return { + type: _Jsep.ARRAY_EXP, + elements: this.gobbleArguments(_Jsep.CBRACK_CODE) + }; + } +}; +var hooks = new Hooks(); +Object.assign(Jsep, { + hooks, + plugins: new Plugins(Jsep), + // Node Types + // ---------- + // This is the full set of types that any JSEP node can be. + // Store them here to save space when minified + COMPOUND: "Compound", + SEQUENCE_EXP: "SequenceExpression", + IDENTIFIER: "Identifier", + MEMBER_EXP: "MemberExpression", + LITERAL: "Literal", + THIS_EXP: "ThisExpression", + CALL_EXP: "CallExpression", + UNARY_EXP: "UnaryExpression", + BINARY_EXP: "BinaryExpression", + ARRAY_EXP: "ArrayExpression", + TAB_CODE: 9, + LF_CODE: 10, + CR_CODE: 13, + SPACE_CODE: 32, + PERIOD_CODE: 46, + // '.' + COMMA_CODE: 44, + // ',' + SQUOTE_CODE: 39, + // single quote + DQUOTE_CODE: 34, + // double quotes + OPAREN_CODE: 40, + // ( + CPAREN_CODE: 41, + // ) + OBRACK_CODE: 91, + // [ + CBRACK_CODE: 93, + // ] + QUMARK_CODE: 63, + // ? + SEMCOL_CODE: 59, + // ; + COLON_CODE: 58, + // : + // Operations + // ---------- + // Use a quickly-accessible map to store all of the unary operators + // Values are set to `1` (it really doesn't matter) + unary_ops: { + "-": 1, + "!": 1, + "~": 1, + "+": 1 + }, + // Also use a map for the binary operations but set their values to their + // binary precedence for quick reference (higher number = higher precedence) + // see [Order of operations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) + binary_ops: { + "||": 1, + "??": 1, + "&&": 2, + "|": 3, + "^": 4, + "&": 5, + "==": 6, + "!=": 6, + "===": 6, + "!==": 6, + "<": 7, + ">": 7, + "<=": 7, + ">=": 7, + "<<": 8, + ">>": 8, + ">>>": 8, + "+": 9, + "-": 9, + "*": 10, + "/": 10, + "%": 10, + "**": 11 + }, + // sets specific binary_ops as right-associative + right_associative: /* @__PURE__ */ new Set(["**"]), + // Additional valid identifier chars, apart from a-z, A-Z and 0-9 (except on the starting char) + additional_identifier_chars: /* @__PURE__ */ new Set(["$", "_"]), + // Literals + // ---------- + // Store the values to return for the various literals we may encounter + literals: { + "true": true, + "false": false, + "null": null + }, + // Except for `this`, which is special. This could be changed to something like `'self'` as well + this_str: "this" +}); +Jsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops); +Jsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops); +var jsep = (expr) => new Jsep(expr).parse(); +var stdClassProps = Object.getOwnPropertyNames(class Test { +}); +Object.getOwnPropertyNames(Jsep).filter((prop) => !stdClassProps.includes(prop) && jsep[prop] === void 0).forEach((m) => { + jsep[m] = Jsep[m]; +}); +jsep.Jsep = Jsep; +var CONDITIONAL_EXP = "ConditionalExpression"; +var ternary = { + name: "ternary", + init(jsep2) { + jsep2.hooks.add("after-expression", function gobbleTernary(env) { + if (env.node && this.code === jsep2.QUMARK_CODE) { + this.index++; + const test = env.node; + const consequent = this.gobbleExpression(); + if (!consequent) { + this.throwError("Expected expression"); + } + this.gobbleSpaces(); + if (this.code === jsep2.COLON_CODE) { + this.index++; + const alternate = this.gobbleExpression(); + if (!alternate) { + this.throwError("Expected expression"); + } + env.node = { + type: CONDITIONAL_EXP, + test, + consequent, + alternate + }; + if (test.operator && jsep2.binary_ops[test.operator] <= 0.9) { + let newTest = test; + while (newTest.right.operator && jsep2.binary_ops[newTest.right.operator] <= 0.9) { + newTest = newTest.right; + } + env.node.test = newTest.right; + newTest.right = env.node; + env.node = test; + } + } else { + this.throwError("Expected :"); + } + } + }); + } +}; +jsep.plugins.register(ternary); +var FSLASH_CODE = 47; +var BSLASH_CODE = 92; +var index = { + name: "regex", + init(jsep2) { + jsep2.hooks.add("gobble-token", function gobbleRegexLiteral(env) { + if (this.code === FSLASH_CODE) { + const patternIndex = ++this.index; + let inCharSet = false; + while (this.index < this.expr.length) { + if (this.code === FSLASH_CODE && !inCharSet) { + const pattern = this.expr.slice(patternIndex, this.index); + let flags = ""; + while (++this.index < this.expr.length) { + const code = this.code; + if (code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57) { + flags += this.char; + } else { + break; + } + } + let value; + try { + value = new RegExp(pattern, flags); + } catch (e) { + this.throwError(e.message); + } + env.node = { + type: jsep2.LITERAL, + value, + raw: this.expr.slice(patternIndex - 1, this.index) + }; + env.node = this.gobbleTokenProperty(env.node); + return env.node; + } + if (this.code === jsep2.OBRACK_CODE) { + inCharSet = true; + } else if (inCharSet && this.code === jsep2.CBRACK_CODE) { + inCharSet = false; + } + this.index += this.code === BSLASH_CODE ? 2 : 1; + } + this.throwError("Unclosed Regex"); + } + }); + } +}; +var PLUS_CODE = 43; +var MINUS_CODE = 45; +var plugin = { + name: "assignment", + assignmentOperators: /* @__PURE__ */ new Set(["=", "*=", "**=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=", "^=", "|=", "||=", "&&=", "??="]), + updateOperators: [PLUS_CODE, MINUS_CODE], + assignmentPrecedence: 0.9, + init(jsep2) { + const updateNodeTypes = [jsep2.IDENTIFIER, jsep2.MEMBER_EXP]; + plugin.assignmentOperators.forEach((op) => jsep2.addBinaryOp(op, plugin.assignmentPrecedence, true)); + jsep2.hooks.add("gobble-token", function gobbleUpdatePrefix(env) { + const code = this.code; + if (plugin.updateOperators.some((c) => c === code && c === this.expr.charCodeAt(this.index + 1))) { + this.index += 2; + env.node = { + type: "UpdateExpression", + operator: code === PLUS_CODE ? "++" : "--", + argument: this.gobbleTokenProperty(this.gobbleIdentifier()), + prefix: true + }; + if (!env.node.argument || !updateNodeTypes.includes(env.node.argument.type)) { + this.throwError(`Unexpected ${env.node.operator}`); + } + } + }); + jsep2.hooks.add("after-token", function gobbleUpdatePostfix(env) { + if (env.node) { + const code = this.code; + if (plugin.updateOperators.some((c) => c === code && c === this.expr.charCodeAt(this.index + 1))) { + if (!updateNodeTypes.includes(env.node.type)) { + this.throwError(`Unexpected ${env.node.operator}`); + } + this.index += 2; + env.node = { + type: "UpdateExpression", + operator: code === PLUS_CODE ? "++" : "--", + argument: env.node, + prefix: false + }; + } + } + }); + jsep2.hooks.add("after-expression", function gobbleAssignment(env) { + if (env.node) { + updateBinariesToAssignments(env.node); + } + }); + function updateBinariesToAssignments(node) { + if (plugin.assignmentOperators.has(node.operator)) { + node.type = "AssignmentExpression"; + updateBinariesToAssignments(node.left); + updateBinariesToAssignments(node.right); + } else if (!node.operator) { + Object.values(node).forEach((val) => { + if (val && typeof val === "object") { + updateBinariesToAssignments(val); + } + }); + } + } + } +}; +jsep.plugins.register(index, plugin); +jsep.addUnaryOp("typeof"); +jsep.addLiteral("null", null); +jsep.addLiteral("undefined", void 0); +var BLOCKED_PROTO_PROPERTIES = /* @__PURE__ */ new Set(["constructor", "__proto__", "__defineGetter__", "__defineSetter__"]); +var SafeEval = { + /** + * @param {jsep.Expression} ast + * @param {Record} subs + */ + evalAst(ast, subs) { + switch (ast.type) { + case "BinaryExpression": + case "LogicalExpression": + return SafeEval.evalBinaryExpression(ast, subs); + case "Compound": + return SafeEval.evalCompound(ast, subs); + case "ConditionalExpression": + return SafeEval.evalConditionalExpression(ast, subs); + case "Identifier": + return SafeEval.evalIdentifier(ast, subs); + case "Literal": + return SafeEval.evalLiteral(ast, subs); + case "MemberExpression": + return SafeEval.evalMemberExpression(ast, subs); + case "UnaryExpression": + return SafeEval.evalUnaryExpression(ast, subs); + case "ArrayExpression": + return SafeEval.evalArrayExpression(ast, subs); + case "CallExpression": + return SafeEval.evalCallExpression(ast, subs); + case "AssignmentExpression": + return SafeEval.evalAssignmentExpression(ast, subs); + default: + throw SyntaxError("Unexpected expression", ast); + } + }, + evalBinaryExpression(ast, subs) { + const result = { + "||": (a, b) => a || b(), + "&&": (a, b) => a && b(), + "|": (a, b) => a | b(), + "^": (a, b) => a ^ b(), + "&": (a, b) => a & b(), + // eslint-disable-next-line eqeqeq -- API + "==": (a, b) => a == b(), + // eslint-disable-next-line eqeqeq -- API + "!=": (a, b) => a != b(), + "===": (a, b) => a === b(), + "!==": (a, b) => a !== b(), + "<": (a, b) => a < b(), + ">": (a, b) => a > b(), + "<=": (a, b) => a <= b(), + ">=": (a, b) => a >= b(), + "<<": (a, b) => a << b(), + ">>": (a, b) => a >> b(), + ">>>": (a, b) => a >>> b(), + "+": (a, b) => a + b(), + "-": (a, b) => a - b(), + "*": (a, b) => a * b(), + "/": (a, b) => a / b(), + "%": (a, b) => a % b() + }[ast.operator](SafeEval.evalAst(ast.left, subs), () => SafeEval.evalAst(ast.right, subs)); + return result; + }, + evalCompound(ast, subs) { + let last; + for (let i = 0; i < ast.body.length; i++) { + if (ast.body[i].type === "Identifier" && ["var", "let", "const"].includes(ast.body[i].name) && ast.body[i + 1] && ast.body[i + 1].type === "AssignmentExpression") { + i += 1; + } + const expr = ast.body[i]; + last = SafeEval.evalAst(expr, subs); + } + return last; + }, + evalConditionalExpression(ast, subs) { + if (SafeEval.evalAst(ast.test, subs)) { + return SafeEval.evalAst(ast.consequent, subs); + } + return SafeEval.evalAst(ast.alternate, subs); + }, + evalIdentifier(ast, subs) { + if (Object.hasOwn(subs, ast.name)) { + return subs[ast.name]; + } + throw ReferenceError(`${ast.name} is not defined`); + }, + evalLiteral(ast) { + return ast.value; + }, + evalMemberExpression(ast, subs) { + const prop = String( + // NOTE: `String(value)` throws error when + // value has overwritten the toString method to return non-string + // i.e. `value = {toString: () => []}` + ast.computed ? SafeEval.evalAst(ast.property) : ast.property.name + // `object.property` property is Identifier + ); + const obj = SafeEval.evalAst(ast.object, subs); + if (obj === void 0 || obj === null) { + throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`); + } + if (!Object.hasOwn(obj, prop) && BLOCKED_PROTO_PROPERTIES.has(prop)) { + throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`); + } + const result = obj[prop]; + if (typeof result === "function") { + return result.bind(obj); + } + return result; + }, + evalUnaryExpression(ast, subs) { + const result = { + "-": (a) => -SafeEval.evalAst(a, subs), + "!": (a) => !SafeEval.evalAst(a, subs), + "~": (a) => ~SafeEval.evalAst(a, subs), + // eslint-disable-next-line no-implicit-coercion -- API + "+": (a) => +SafeEval.evalAst(a, subs), + typeof: (a) => typeof SafeEval.evalAst(a, subs) + }[ast.operator](ast.argument); + return result; + }, + evalArrayExpression(ast, subs) { + return ast.elements.map((el) => SafeEval.evalAst(el, subs)); + }, + evalCallExpression(ast, subs) { + const args = ast.arguments.map((arg) => SafeEval.evalAst(arg, subs)); + const func = SafeEval.evalAst(ast.callee, subs); + return func(...args); + }, + evalAssignmentExpression(ast, subs) { + if (ast.left.type !== "Identifier") { + throw SyntaxError("Invalid left-hand side in assignment"); + } + const id = ast.left.name; + const value = SafeEval.evalAst(ast.right, subs); + subs[id] = value; + return subs[id]; + } +}; +var SafeScript = class { + /** + * @param {string} expr Expression to evaluate + */ + constructor(expr) { + this.code = expr; + this.ast = jsep(this.code); + } + /** + * @param {object} context Object whose items will be added + * to evaluation + * @returns {EvaluatedResult} Result of evaluated code + */ + runInNewContext(context) { + const keyMap = Object.assign(/* @__PURE__ */ Object.create(null), context); + return SafeEval.evalAst(this.ast, keyMap); + } +}; function push(arr, item) { arr = arr.slice(); arr.push(item); @@ -84,7 +1306,7 @@ function JSONPath(opts, expr, obj, callback, otherTypeCallback) { this.path = opts.path || expr; this.resultType = opts.resultType || "value"; this.flatten = opts.flatten || false; - this.wrap = hasOwnProp.call(opts, "wrap") ? opts.wrap : true; + this.wrap = Object.hasOwn(opts, "wrap") ? opts.wrap : true; this.sandbox = opts.sandbox || {}; this.eval = opts.eval === void 0 ? "safe" : opts.eval; this.ignoreEvalErrors = typeof opts.ignoreEvalErrors === "undefined" ? false : opts.ignoreEvalErrors; @@ -127,21 +1349,21 @@ JSONPath.prototype.evaluate = function(expr, json, callback, otherTypeCallback) if (!expr.path && expr.path !== "") { throw new TypeError('You must supply a "path" property when providing an object argument to JSONPath.evaluate().'); } - if (!hasOwnProp.call(expr, "json")) { + if (!Object.hasOwn(expr, "json")) { throw new TypeError('You must supply a "json" property when providing an object argument to JSONPath.evaluate().'); } ({ json } = expr); - flatten = hasOwnProp.call(expr, "flatten") ? expr.flatten : flatten; - this.currResultType = hasOwnProp.call(expr, "resultType") ? expr.resultType : this.currResultType; - this.currSandbox = hasOwnProp.call(expr, "sandbox") ? expr.sandbox : this.currSandbox; - wrap = hasOwnProp.call(expr, "wrap") ? expr.wrap : wrap; - this.currEval = hasOwnProp.call(expr, "eval") ? expr.eval : this.currEval; - callback = hasOwnProp.call(expr, "callback") ? expr.callback : callback; - this.currOtherTypeCallback = hasOwnProp.call(expr, "otherTypeCallback") ? expr.otherTypeCallback : this.currOtherTypeCallback; - currParent = hasOwnProp.call(expr, "parent") ? expr.parent : currParent; - currParentProperty = hasOwnProp.call(expr, "parentProperty") ? expr.parentProperty : currParentProperty; + flatten = Object.hasOwn(expr, "flatten") ? expr.flatten : flatten; + this.currResultType = Object.hasOwn(expr, "resultType") ? expr.resultType : this.currResultType; + this.currSandbox = Object.hasOwn(expr, "sandbox") ? expr.sandbox : this.currSandbox; + wrap = Object.hasOwn(expr, "wrap") ? expr.wrap : wrap; + this.currEval = Object.hasOwn(expr, "eval") ? expr.eval : this.currEval; + callback = Object.hasOwn(expr, "callback") ? expr.callback : callback; + this.currOtherTypeCallback = Object.hasOwn(expr, "otherTypeCallback") ? expr.otherTypeCallback : this.currOtherTypeCallback; + currParent = Object.hasOwn(expr, "parent") ? expr.parent : currParent; + currParentProperty = Object.hasOwn(expr, "parentProperty") ? expr.parentProperty : currParentProperty; expr = expr.path; } currParent = currParent || null; @@ -228,7 +1450,7 @@ JSONPath.prototype._trace = function(expr, val, path, parent, parentPropName, ca ret.push(elems); } } - if ((typeof loc !== "string" || literalPriority) && val && hasOwnProp.call(val, loc)) { + if ((typeof loc !== "string" || literalPriority) && val && Object.hasOwn(val, loc)) { addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr)); } else if (loc === "*") { this._walk(val, (m) => { @@ -287,7 +1509,7 @@ JSONPath.prototype._trace = function(expr, val, path, parent, parentPropName, ca if (this.currEval === false) { throw new Error("Eval [(expr)] prevented in JSONPath expression."); } - addRet(this._trace(unshift(this._eval(loc, val, path[path.length - 1], path.slice(0, -1), parent, parentPropName), x), val, path, parent, parentPropName, callback, hasArrExpr)); + addRet(this._trace(unshift(this._eval(loc, val, path.at(-1), path.slice(0, -1), parent, parentPropName), x), val, path, parent, parentPropName, callback, hasArrExpr)); } else if (loc[0] === "@") { let addType = false; const valueType = loc.slice(1, -2); @@ -351,7 +1573,7 @@ JSONPath.prototype._trace = function(expr, val, path, parent, parentPropName, ca this._handleCallback(retObj, callback, "value"); return retObj; } - } else if (loc[0] === "`" && val && hasOwnProp.call(val, loc.slice(1))) { + } else if (loc[0] === "`" && val && Object.hasOwn(val, loc.slice(1))) { const locProp = loc.slice(1); addRet(this._trace(x, val[locProp], push(path, locProp), val, locProp, callback, hasArrExpr, true)); } else if (loc.includes(",")) { @@ -359,7 +1581,7 @@ JSONPath.prototype._trace = function(expr, val, path, parent, parentPropName, ca for (const part of parts) { addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback, true)); } - } else if (!literalPriority && val && hasOwnProp.call(val, loc)) { + } else if (!literalPriority && val && Object.hasOwn(val, loc)) { addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr, true)); } if (this._hasParentSelector) { @@ -423,15 +1645,15 @@ JSONPath.prototype._eval = function(code, _v, _vname, path, parent, parentPropNa } const scriptCacheKey = this.currEval + "Script:" + code; if (!JSONPath.cache[scriptCacheKey]) { - let script = code.replace(/@parentProperty/gu, "_$_parentProperty").replace(/@parent/gu, "_$_parent").replace(/@property/gu, "_$_property").replace(/@root/gu, "_$_root").replace(/@([.\s)[])/gu, "_$_v$1"); + let script = code.replaceAll("@parentProperty", "_$_parentProperty").replaceAll("@parent", "_$_parent").replaceAll("@property", "_$_property").replaceAll("@root", "_$_root").replaceAll(/@([.\s)[])/gu, "_$_v$1"); if (containsPath) { - script = script.replace(/@path/gu, "_$_path"); + script = script.replaceAll("@path", "_$_path"); } if (this.currEval === "safe" || this.currEval === true || this.currEval === void 0) { JSONPath.cache[scriptCacheKey] = new this.safeVm.Script(script); } else if (this.currEval === "native") { JSONPath.cache[scriptCacheKey] = new this.vm.Script(script); - } else if (typeof this.currEval === "function" && this.currEval.prototype && hasOwnProp.call(this.currEval.prototype, "runInNewContext")) { + } else if (typeof this.currEval === "function" && this.currEval.prototype && Object.hasOwn(this.currEval.prototype, "runInNewContext")) { const CurrEval = this.currEval; JSONPath.cache[scriptCacheKey] = new CurrEval(script); } else if (typeof this.currEval === "function") { @@ -467,7 +1689,7 @@ JSONPath.toPointer = function(pointer) { let p = ""; for (let i = 1; i < n; i++) { if (!/^(~|\^|@.*?\(\))$/u.test(x[i])) { - p += "/" + x[i].toString().replace(/~/gu, "~0").replace(/\//gu, "~1"); + p += "/" + x[i].toString().replaceAll("~", "~0").replaceAll("/", "~1"); } } return p; @@ -480,13 +1702,13 @@ JSONPath.toPathArray = function(expr) { return cache[expr].concat(); } const subx = []; - const normalized = expr.replace(/@(?:null|boolean|number|string|integer|undefined|nonFinite|scalar|array|object|function|other)\(\)/gu, ";$&;").replace(/[['](\??\(.*?\))[\]'](?!.\])/gu, function($0, $1) { + const normalized = expr.replaceAll(/@(?:null|boolean|number|string|integer|undefined|nonFinite|scalar|array|object|function|other)\(\)/gu, ";$&;").replaceAll(/[['](\??\(.*?\))[\]'](?!.\])/gu, function($0, $1) { return "[#" + (subx.push($1) - 1) + "]"; - }).replace(/\[['"]([^'\]]*)['"]\]/gu, function($0, prop) { - return "['" + prop.replace(/\./gu, "%@%").replace(/~/gu, "%%@@%%") + "']"; - }).replace(/~/gu, ";~;").replace(/['"]?\.['"]?(?![^[]*\])|\[['"]?/gu, ";").replace(/%@%/gu, ".").replace(/%%@@%%/gu, "~").replace(/(?:;)?(\^+)(?:;)?/gu, function($0, ups) { + }).replaceAll(/\[['"]([^'\]]*)['"]\]/gu, function($0, prop) { + return "['" + prop.replaceAll(".", "%@%").replaceAll("~", "%%@@%%") + "']"; + }).replaceAll("~", ";~;").replaceAll(/['"]?\.['"]?(?![^[]*\])|\[['"]?/gu, ";").replaceAll("%@%", ".").replaceAll("%%@@%%", "~").replaceAll(/(?:;)?(\^+)(?:;)?/gu, function($0, ups) { return ";" + ups.split("").join(";") + ";"; - }).replace(/;;;|;;/gu, ";..;").replace(/;$|'?\]|'$/gu, ""); + }).replaceAll(/;;;|;;/gu, ";..;").replaceAll(/;$|'?\]|'$/gu, ""); const exprList = normalized.split(";").map(function(exp) { const match = exp.match(/#(\d+)/u); return !match || !match[1] ? exp : subx[match[1]]; @@ -494,12 +1716,13 @@ JSONPath.toPathArray = function(expr) { cache[expr] = exprList; return cache[expr].concat(); }; +JSONPath.prototype.safeVm = { + Script: SafeScript +}; JSONPath.prototype.vm = import_vm.default; -JSONPath.prototype.safeVm = import_vm.default; -var SafeScript = import_vm.default.Script; // src/index.ts -var plugin = { +var plugin2 = { filter: { name: "JSONPath", description: "Filter JSONPath", diff --git a/src-tauri/vendored/plugins/filter-jsonpath/package.json b/src-tauri/vendored/plugins/filter-jsonpath/package.json index 4d1a1c5a9..028816ac8 100644 --- a/src-tauri/vendored/plugins/filter-jsonpath/package.json +++ b/src-tauri/vendored/plugins/filter-jsonpath/package.json @@ -7,7 +7,7 @@ "dev": "yaakcli dev ./src/index.js" }, "dependencies": { - "jsonpath-plus": "^9.0.0" + "jsonpath-plus": "^10.3.0" }, "devDependencies": { "@types/jsonpath": "^0.2.4" diff --git a/src-tauri/vendored/plugins/template-function-json/build/index.js b/src-tauri/vendored/plugins/template-function-json/build/index.js new file mode 100644 index 000000000..c548fddec --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-json/build/index.js @@ -0,0 +1,1769 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var src_exports = {}; +__export(src_exports, { + plugin: () => plugin2 +}); +module.exports = __toCommonJS(src_exports); + +// node_modules/jsonpath-plus/dist/index-node-esm.js +var import_vm = __toESM(require("vm"), 1); +var Hooks = class { + /** + * @callback HookCallback + * @this {*|Jsep} this + * @param {Jsep} env + * @returns: void + */ + /** + * Adds the given callback to the list of callbacks for the given hook. + * + * The callback will be invoked when the hook it is registered for is run. + * + * One callback function can be registered to multiple hooks and the same hook multiple times. + * + * @param {string|object} name The name of the hook, or an object of callbacks keyed by name + * @param {HookCallback|boolean} callback The callback function which is given environment variables. + * @param {?boolean} [first=false] Will add the hook to the top of the list (defaults to the bottom) + * @public + */ + add(name, callback, first) { + if (typeof arguments[0] != "string") { + for (let name2 in arguments[0]) { + this.add(name2, arguments[0][name2], arguments[1]); + } + } else { + (Array.isArray(name) ? name : [name]).forEach(function(name2) { + this[name2] = this[name2] || []; + if (callback) { + this[name2][first ? "unshift" : "push"](callback); + } + }, this); + } + } + /** + * Runs a hook invoking all registered callbacks with the given environment variables. + * + * Callbacks will be invoked synchronously and in the order in which they were registered. + * + * @param {string} name The name of the hook. + * @param {Object} env The environment variables of the hook passed to all callbacks registered. + * @public + */ + run(name, env) { + this[name] = this[name] || []; + this[name].forEach(function(callback) { + callback.call(env && env.context ? env.context : env, env); + }); + } +}; +var Plugins = class { + constructor(jsep2) { + this.jsep = jsep2; + this.registered = {}; + } + /** + * @callback PluginSetup + * @this {Jsep} jsep + * @returns: void + */ + /** + * Adds the given plugin(s) to the registry + * + * @param {object} plugins + * @param {string} plugins.name The name of the plugin + * @param {PluginSetup} plugins.init The init function + * @public + */ + register(...plugins) { + plugins.forEach((plugin3) => { + if (typeof plugin3 !== "object" || !plugin3.name || !plugin3.init) { + throw new Error("Invalid JSEP plugin format"); + } + if (this.registered[plugin3.name]) { + return; + } + plugin3.init(this.jsep); + this.registered[plugin3.name] = plugin3; + }); + } +}; +var Jsep = class _Jsep { + /** + * @returns {string} + */ + static get version() { + return "1.4.0"; + } + /** + * @returns {string} + */ + static toString() { + return "JavaScript Expression Parser (JSEP) v" + _Jsep.version; + } + // ==================== CONFIG ================================ + /** + * @method addUnaryOp + * @param {string} op_name The name of the unary op to add + * @returns {Jsep} + */ + static addUnaryOp(op_name) { + _Jsep.max_unop_len = Math.max(op_name.length, _Jsep.max_unop_len); + _Jsep.unary_ops[op_name] = 1; + return _Jsep; + } + /** + * @method jsep.addBinaryOp + * @param {string} op_name The name of the binary op to add + * @param {number} precedence The precedence of the binary op (can be a float). Higher number = higher precedence + * @param {boolean} [isRightAssociative=false] whether operator is right-associative + * @returns {Jsep} + */ + static addBinaryOp(op_name, precedence, isRightAssociative) { + _Jsep.max_binop_len = Math.max(op_name.length, _Jsep.max_binop_len); + _Jsep.binary_ops[op_name] = precedence; + if (isRightAssociative) { + _Jsep.right_associative.add(op_name); + } else { + _Jsep.right_associative.delete(op_name); + } + return _Jsep; + } + /** + * @method addIdentifierChar + * @param {string} char The additional character to treat as a valid part of an identifier + * @returns {Jsep} + */ + static addIdentifierChar(char) { + _Jsep.additional_identifier_chars.add(char); + return _Jsep; + } + /** + * @method addLiteral + * @param {string} literal_name The name of the literal to add + * @param {*} literal_value The value of the literal + * @returns {Jsep} + */ + static addLiteral(literal_name, literal_value) { + _Jsep.literals[literal_name] = literal_value; + return _Jsep; + } + /** + * @method removeUnaryOp + * @param {string} op_name The name of the unary op to remove + * @returns {Jsep} + */ + static removeUnaryOp(op_name) { + delete _Jsep.unary_ops[op_name]; + if (op_name.length === _Jsep.max_unop_len) { + _Jsep.max_unop_len = _Jsep.getMaxKeyLen(_Jsep.unary_ops); + } + return _Jsep; + } + /** + * @method removeAllUnaryOps + * @returns {Jsep} + */ + static removeAllUnaryOps() { + _Jsep.unary_ops = {}; + _Jsep.max_unop_len = 0; + return _Jsep; + } + /** + * @method removeIdentifierChar + * @param {string} char The additional character to stop treating as a valid part of an identifier + * @returns {Jsep} + */ + static removeIdentifierChar(char) { + _Jsep.additional_identifier_chars.delete(char); + return _Jsep; + } + /** + * @method removeBinaryOp + * @param {string} op_name The name of the binary op to remove + * @returns {Jsep} + */ + static removeBinaryOp(op_name) { + delete _Jsep.binary_ops[op_name]; + if (op_name.length === _Jsep.max_binop_len) { + _Jsep.max_binop_len = _Jsep.getMaxKeyLen(_Jsep.binary_ops); + } + _Jsep.right_associative.delete(op_name); + return _Jsep; + } + /** + * @method removeAllBinaryOps + * @returns {Jsep} + */ + static removeAllBinaryOps() { + _Jsep.binary_ops = {}; + _Jsep.max_binop_len = 0; + return _Jsep; + } + /** + * @method removeLiteral + * @param {string} literal_name The name of the literal to remove + * @returns {Jsep} + */ + static removeLiteral(literal_name) { + delete _Jsep.literals[literal_name]; + return _Jsep; + } + /** + * @method removeAllLiterals + * @returns {Jsep} + */ + static removeAllLiterals() { + _Jsep.literals = {}; + return _Jsep; + } + // ==================== END CONFIG ============================ + /** + * @returns {string} + */ + get char() { + return this.expr.charAt(this.index); + } + /** + * @returns {number} + */ + get code() { + return this.expr.charCodeAt(this.index); + } + /** + * @param {string} expr a string with the passed in express + * @returns Jsep + */ + constructor(expr) { + this.expr = expr; + this.index = 0; + } + /** + * static top-level parser + * @returns {jsep.Expression} + */ + static parse(expr) { + return new _Jsep(expr).parse(); + } + /** + * Get the longest key length of any object + * @param {object} obj + * @returns {number} + */ + static getMaxKeyLen(obj) { + return Math.max(0, ...Object.keys(obj).map((k) => k.length)); + } + /** + * `ch` is a character code in the next three functions + * @param {number} ch + * @returns {boolean} + */ + static isDecimalDigit(ch) { + return ch >= 48 && ch <= 57; + } + /** + * Returns the precedence of a binary operator or `0` if it isn't a binary operator. Can be float. + * @param {string} op_val + * @returns {number} + */ + static binaryPrecedence(op_val) { + return _Jsep.binary_ops[op_val] || 0; + } + /** + * Looks for start of identifier + * @param {number} ch + * @returns {boolean} + */ + static isIdentifierStart(ch) { + return ch >= 65 && ch <= 90 || // A...Z + ch >= 97 && ch <= 122 || // a...z + ch >= 128 && !_Jsep.binary_ops[String.fromCharCode(ch)] || // any non-ASCII that is not an operator + _Jsep.additional_identifier_chars.has(String.fromCharCode(ch)); + } + /** + * @param {number} ch + * @returns {boolean} + */ + static isIdentifierPart(ch) { + return _Jsep.isIdentifierStart(ch) || _Jsep.isDecimalDigit(ch); + } + /** + * throw error at index of the expression + * @param {string} message + * @throws + */ + throwError(message) { + const error = new Error(message + " at character " + this.index); + error.index = this.index; + error.description = message; + throw error; + } + /** + * Run a given hook + * @param {string} name + * @param {jsep.Expression|false} [node] + * @returns {?jsep.Expression} + */ + runHook(name, node) { + if (_Jsep.hooks[name]) { + const env = { + context: this, + node + }; + _Jsep.hooks.run(name, env); + return env.node; + } + return node; + } + /** + * Runs a given hook until one returns a node + * @param {string} name + * @returns {?jsep.Expression} + */ + searchHook(name) { + if (_Jsep.hooks[name]) { + const env = { + context: this + }; + _Jsep.hooks[name].find(function(callback) { + callback.call(env.context, env); + return env.node; + }); + return env.node; + } + } + /** + * Push `index` up to the next non-space character + */ + gobbleSpaces() { + let ch = this.code; + while (ch === _Jsep.SPACE_CODE || ch === _Jsep.TAB_CODE || ch === _Jsep.LF_CODE || ch === _Jsep.CR_CODE) { + ch = this.expr.charCodeAt(++this.index); + } + this.runHook("gobble-spaces"); + } + /** + * Top-level method to parse all expressions and returns compound or single node + * @returns {jsep.Expression} + */ + parse() { + this.runHook("before-all"); + const nodes = this.gobbleExpressions(); + const node = nodes.length === 1 ? nodes[0] : { + type: _Jsep.COMPOUND, + body: nodes + }; + return this.runHook("after-all", node); + } + /** + * top-level parser (but can be reused within as well) + * @param {number} [untilICode] + * @returns {jsep.Expression[]} + */ + gobbleExpressions(untilICode) { + let nodes = [], ch_i, node; + while (this.index < this.expr.length) { + ch_i = this.code; + if (ch_i === _Jsep.SEMCOL_CODE || ch_i === _Jsep.COMMA_CODE) { + this.index++; + } else { + if (node = this.gobbleExpression()) { + nodes.push(node); + } else if (this.index < this.expr.length) { + if (ch_i === untilICode) { + break; + } + this.throwError('Unexpected "' + this.char + '"'); + } + } + } + return nodes; + } + /** + * The main parsing function. + * @returns {?jsep.Expression} + */ + gobbleExpression() { + const node = this.searchHook("gobble-expression") || this.gobbleBinaryExpression(); + this.gobbleSpaces(); + return this.runHook("after-expression", node); + } + /** + * Search for the operation portion of the string (e.g. `+`, `===`) + * Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`) + * and move down from 3 to 2 to 1 character until a matching binary operation is found + * then, return that binary operation + * @returns {string|boolean} + */ + gobbleBinaryOp() { + this.gobbleSpaces(); + let to_check = this.expr.substr(this.index, _Jsep.max_binop_len); + let tc_len = to_check.length; + while (tc_len > 0) { + if (_Jsep.binary_ops.hasOwnProperty(to_check) && (!_Jsep.isIdentifierStart(this.code) || this.index + to_check.length < this.expr.length && !_Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))) { + this.index += tc_len; + return to_check; + } + to_check = to_check.substr(0, --tc_len); + } + return false; + } + /** + * This function is responsible for gobbling an individual expression, + * e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)` + * @returns {?jsep.BinaryExpression} + */ + gobbleBinaryExpression() { + let node, biop, prec, stack, biop_info, left, right, i, cur_biop; + left = this.gobbleToken(); + if (!left) { + return left; + } + biop = this.gobbleBinaryOp(); + if (!biop) { + return left; + } + biop_info = { + value: biop, + prec: _Jsep.binaryPrecedence(biop), + right_a: _Jsep.right_associative.has(biop) + }; + right = this.gobbleToken(); + if (!right) { + this.throwError("Expected expression after " + biop); + } + stack = [left, biop_info, right]; + while (biop = this.gobbleBinaryOp()) { + prec = _Jsep.binaryPrecedence(biop); + if (prec === 0) { + this.index -= biop.length; + break; + } + biop_info = { + value: biop, + prec, + right_a: _Jsep.right_associative.has(biop) + }; + cur_biop = biop; + const comparePrev = (prev) => biop_info.right_a && prev.right_a ? prec > prev.prec : prec <= prev.prec; + while (stack.length > 2 && comparePrev(stack[stack.length - 2])) { + right = stack.pop(); + biop = stack.pop().value; + left = stack.pop(); + node = { + type: _Jsep.BINARY_EXP, + operator: biop, + left, + right + }; + stack.push(node); + } + node = this.gobbleToken(); + if (!node) { + this.throwError("Expected expression after " + cur_biop); + } + stack.push(biop_info, node); + } + i = stack.length - 1; + node = stack[i]; + while (i > 1) { + node = { + type: _Jsep.BINARY_EXP, + operator: stack[i - 1].value, + left: stack[i - 2], + right: node + }; + i -= 2; + } + return node; + } + /** + * An individual part of a binary expression: + * e.g. `foo.bar(baz)`, `1`, `"abc"`, `(a % 2)` (because it's in parenthesis) + * @returns {boolean|jsep.Expression} + */ + gobbleToken() { + let ch, to_check, tc_len, node; + this.gobbleSpaces(); + node = this.searchHook("gobble-token"); + if (node) { + return this.runHook("after-token", node); + } + ch = this.code; + if (_Jsep.isDecimalDigit(ch) || ch === _Jsep.PERIOD_CODE) { + return this.gobbleNumericLiteral(); + } + if (ch === _Jsep.SQUOTE_CODE || ch === _Jsep.DQUOTE_CODE) { + node = this.gobbleStringLiteral(); + } else if (ch === _Jsep.OBRACK_CODE) { + node = this.gobbleArray(); + } else { + to_check = this.expr.substr(this.index, _Jsep.max_unop_len); + tc_len = to_check.length; + while (tc_len > 0) { + if (_Jsep.unary_ops.hasOwnProperty(to_check) && (!_Jsep.isIdentifierStart(this.code) || this.index + to_check.length < this.expr.length && !_Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))) { + this.index += tc_len; + const argument = this.gobbleToken(); + if (!argument) { + this.throwError("missing unaryOp argument"); + } + return this.runHook("after-token", { + type: _Jsep.UNARY_EXP, + operator: to_check, + argument, + prefix: true + }); + } + to_check = to_check.substr(0, --tc_len); + } + if (_Jsep.isIdentifierStart(ch)) { + node = this.gobbleIdentifier(); + if (_Jsep.literals.hasOwnProperty(node.name)) { + node = { + type: _Jsep.LITERAL, + value: _Jsep.literals[node.name], + raw: node.name + }; + } else if (node.name === _Jsep.this_str) { + node = { + type: _Jsep.THIS_EXP + }; + } + } else if (ch === _Jsep.OPAREN_CODE) { + node = this.gobbleGroup(); + } + } + if (!node) { + return this.runHook("after-token", false); + } + node = this.gobbleTokenProperty(node); + return this.runHook("after-token", node); + } + /** + * Gobble properties of of identifiers/strings/arrays/groups. + * e.g. `foo`, `bar.baz`, `foo['bar'].baz` + * It also gobbles function calls: + * e.g. `Math.acos(obj.angle)` + * @param {jsep.Expression} node + * @returns {jsep.Expression} + */ + gobbleTokenProperty(node) { + this.gobbleSpaces(); + let ch = this.code; + while (ch === _Jsep.PERIOD_CODE || ch === _Jsep.OBRACK_CODE || ch === _Jsep.OPAREN_CODE || ch === _Jsep.QUMARK_CODE) { + let optional; + if (ch === _Jsep.QUMARK_CODE) { + if (this.expr.charCodeAt(this.index + 1) !== _Jsep.PERIOD_CODE) { + break; + } + optional = true; + this.index += 2; + this.gobbleSpaces(); + ch = this.code; + } + this.index++; + if (ch === _Jsep.OBRACK_CODE) { + node = { + type: _Jsep.MEMBER_EXP, + computed: true, + object: node, + property: this.gobbleExpression() + }; + if (!node.property) { + this.throwError('Unexpected "' + this.char + '"'); + } + this.gobbleSpaces(); + ch = this.code; + if (ch !== _Jsep.CBRACK_CODE) { + this.throwError("Unclosed ["); + } + this.index++; + } else if (ch === _Jsep.OPAREN_CODE) { + node = { + type: _Jsep.CALL_EXP, + "arguments": this.gobbleArguments(_Jsep.CPAREN_CODE), + callee: node + }; + } else if (ch === _Jsep.PERIOD_CODE || optional) { + if (optional) { + this.index--; + } + this.gobbleSpaces(); + node = { + type: _Jsep.MEMBER_EXP, + computed: false, + object: node, + property: this.gobbleIdentifier() + }; + } + if (optional) { + node.optional = true; + } + this.gobbleSpaces(); + ch = this.code; + } + return node; + } + /** + * Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to + * keep track of everything in the numeric literal and then calling `parseFloat` on that string + * @returns {jsep.Literal} + */ + gobbleNumericLiteral() { + let number = "", ch, chCode; + while (_Jsep.isDecimalDigit(this.code)) { + number += this.expr.charAt(this.index++); + } + if (this.code === _Jsep.PERIOD_CODE) { + number += this.expr.charAt(this.index++); + while (_Jsep.isDecimalDigit(this.code)) { + number += this.expr.charAt(this.index++); + } + } + ch = this.char; + if (ch === "e" || ch === "E") { + number += this.expr.charAt(this.index++); + ch = this.char; + if (ch === "+" || ch === "-") { + number += this.expr.charAt(this.index++); + } + while (_Jsep.isDecimalDigit(this.code)) { + number += this.expr.charAt(this.index++); + } + if (!_Jsep.isDecimalDigit(this.expr.charCodeAt(this.index - 1))) { + this.throwError("Expected exponent (" + number + this.char + ")"); + } + } + chCode = this.code; + if (_Jsep.isIdentifierStart(chCode)) { + this.throwError("Variable names cannot start with a number (" + number + this.char + ")"); + } else if (chCode === _Jsep.PERIOD_CODE || number.length === 1 && number.charCodeAt(0) === _Jsep.PERIOD_CODE) { + this.throwError("Unexpected period"); + } + return { + type: _Jsep.LITERAL, + value: parseFloat(number), + raw: number + }; + } + /** + * Parses a string literal, staring with single or double quotes with basic support for escape codes + * e.g. `"hello world"`, `'this is\nJSEP'` + * @returns {jsep.Literal} + */ + gobbleStringLiteral() { + let str = ""; + const startIndex = this.index; + const quote = this.expr.charAt(this.index++); + let closed = false; + while (this.index < this.expr.length) { + let ch = this.expr.charAt(this.index++); + if (ch === quote) { + closed = true; + break; + } else if (ch === "\\") { + ch = this.expr.charAt(this.index++); + switch (ch) { + case "n": + str += "\n"; + break; + case "r": + str += "\r"; + break; + case "t": + str += " "; + break; + case "b": + str += "\b"; + break; + case "f": + str += "\f"; + break; + case "v": + str += "\v"; + break; + default: + str += ch; + } + } else { + str += ch; + } + } + if (!closed) { + this.throwError('Unclosed quote after "' + str + '"'); + } + return { + type: _Jsep.LITERAL, + value: str, + raw: this.expr.substring(startIndex, this.index) + }; + } + /** + * Gobbles only identifiers + * e.g.: `foo`, `_value`, `$x1` + * Also, this function checks if that identifier is a literal: + * (e.g. `true`, `false`, `null`) or `this` + * @returns {jsep.Identifier} + */ + gobbleIdentifier() { + let ch = this.code, start = this.index; + if (_Jsep.isIdentifierStart(ch)) { + this.index++; + } else { + this.throwError("Unexpected " + this.char); + } + while (this.index < this.expr.length) { + ch = this.code; + if (_Jsep.isIdentifierPart(ch)) { + this.index++; + } else { + break; + } + } + return { + type: _Jsep.IDENTIFIER, + name: this.expr.slice(start, this.index) + }; + } + /** + * Gobbles a list of arguments within the context of a function call + * or array literal. This function also assumes that the opening character + * `(` or `[` has already been gobbled, and gobbles expressions and commas + * until the terminator character `)` or `]` is encountered. + * e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]` + * @param {number} termination + * @returns {jsep.Expression[]} + */ + gobbleArguments(termination) { + const args = []; + let closed = false; + let separator_count = 0; + while (this.index < this.expr.length) { + this.gobbleSpaces(); + let ch_i = this.code; + if (ch_i === termination) { + closed = true; + this.index++; + if (termination === _Jsep.CPAREN_CODE && separator_count && separator_count >= args.length) { + this.throwError("Unexpected token " + String.fromCharCode(termination)); + } + break; + } else if (ch_i === _Jsep.COMMA_CODE) { + this.index++; + separator_count++; + if (separator_count !== args.length) { + if (termination === _Jsep.CPAREN_CODE) { + this.throwError("Unexpected token ,"); + } else if (termination === _Jsep.CBRACK_CODE) { + for (let arg = args.length; arg < separator_count; arg++) { + args.push(null); + } + } + } + } else if (args.length !== separator_count && separator_count !== 0) { + this.throwError("Expected comma"); + } else { + const node = this.gobbleExpression(); + if (!node || node.type === _Jsep.COMPOUND) { + this.throwError("Expected comma"); + } + args.push(node); + } + } + if (!closed) { + this.throwError("Expected " + String.fromCharCode(termination)); + } + return args; + } + /** + * Responsible for parsing a group of things within parentheses `()` + * that have no identifier in front (so not a function call) + * This function assumes that it needs to gobble the opening parenthesis + * and then tries to gobble everything within that parenthesis, assuming + * that the next thing it should see is the close parenthesis. If not, + * then the expression probably doesn't have a `)` + * @returns {boolean|jsep.Expression} + */ + gobbleGroup() { + this.index++; + let nodes = this.gobbleExpressions(_Jsep.CPAREN_CODE); + if (this.code === _Jsep.CPAREN_CODE) { + this.index++; + if (nodes.length === 1) { + return nodes[0]; + } else if (!nodes.length) { + return false; + } else { + return { + type: _Jsep.SEQUENCE_EXP, + expressions: nodes + }; + } + } else { + this.throwError("Unclosed ("); + } + } + /** + * Responsible for parsing Array literals `[1, 2, 3]` + * This function assumes that it needs to gobble the opening bracket + * and then tries to gobble the expressions as arguments. + * @returns {jsep.ArrayExpression} + */ + gobbleArray() { + this.index++; + return { + type: _Jsep.ARRAY_EXP, + elements: this.gobbleArguments(_Jsep.CBRACK_CODE) + }; + } +}; +var hooks = new Hooks(); +Object.assign(Jsep, { + hooks, + plugins: new Plugins(Jsep), + // Node Types + // ---------- + // This is the full set of types that any JSEP node can be. + // Store them here to save space when minified + COMPOUND: "Compound", + SEQUENCE_EXP: "SequenceExpression", + IDENTIFIER: "Identifier", + MEMBER_EXP: "MemberExpression", + LITERAL: "Literal", + THIS_EXP: "ThisExpression", + CALL_EXP: "CallExpression", + UNARY_EXP: "UnaryExpression", + BINARY_EXP: "BinaryExpression", + ARRAY_EXP: "ArrayExpression", + TAB_CODE: 9, + LF_CODE: 10, + CR_CODE: 13, + SPACE_CODE: 32, + PERIOD_CODE: 46, + // '.' + COMMA_CODE: 44, + // ',' + SQUOTE_CODE: 39, + // single quote + DQUOTE_CODE: 34, + // double quotes + OPAREN_CODE: 40, + // ( + CPAREN_CODE: 41, + // ) + OBRACK_CODE: 91, + // [ + CBRACK_CODE: 93, + // ] + QUMARK_CODE: 63, + // ? + SEMCOL_CODE: 59, + // ; + COLON_CODE: 58, + // : + // Operations + // ---------- + // Use a quickly-accessible map to store all of the unary operators + // Values are set to `1` (it really doesn't matter) + unary_ops: { + "-": 1, + "!": 1, + "~": 1, + "+": 1 + }, + // Also use a map for the binary operations but set their values to their + // binary precedence for quick reference (higher number = higher precedence) + // see [Order of operations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) + binary_ops: { + "||": 1, + "??": 1, + "&&": 2, + "|": 3, + "^": 4, + "&": 5, + "==": 6, + "!=": 6, + "===": 6, + "!==": 6, + "<": 7, + ">": 7, + "<=": 7, + ">=": 7, + "<<": 8, + ">>": 8, + ">>>": 8, + "+": 9, + "-": 9, + "*": 10, + "/": 10, + "%": 10, + "**": 11 + }, + // sets specific binary_ops as right-associative + right_associative: /* @__PURE__ */ new Set(["**"]), + // Additional valid identifier chars, apart from a-z, A-Z and 0-9 (except on the starting char) + additional_identifier_chars: /* @__PURE__ */ new Set(["$", "_"]), + // Literals + // ---------- + // Store the values to return for the various literals we may encounter + literals: { + "true": true, + "false": false, + "null": null + }, + // Except for `this`, which is special. This could be changed to something like `'self'` as well + this_str: "this" +}); +Jsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops); +Jsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops); +var jsep = (expr) => new Jsep(expr).parse(); +var stdClassProps = Object.getOwnPropertyNames(class Test { +}); +Object.getOwnPropertyNames(Jsep).filter((prop) => !stdClassProps.includes(prop) && jsep[prop] === void 0).forEach((m) => { + jsep[m] = Jsep[m]; +}); +jsep.Jsep = Jsep; +var CONDITIONAL_EXP = "ConditionalExpression"; +var ternary = { + name: "ternary", + init(jsep2) { + jsep2.hooks.add("after-expression", function gobbleTernary(env) { + if (env.node && this.code === jsep2.QUMARK_CODE) { + this.index++; + const test = env.node; + const consequent = this.gobbleExpression(); + if (!consequent) { + this.throwError("Expected expression"); + } + this.gobbleSpaces(); + if (this.code === jsep2.COLON_CODE) { + this.index++; + const alternate = this.gobbleExpression(); + if (!alternate) { + this.throwError("Expected expression"); + } + env.node = { + type: CONDITIONAL_EXP, + test, + consequent, + alternate + }; + if (test.operator && jsep2.binary_ops[test.operator] <= 0.9) { + let newTest = test; + while (newTest.right.operator && jsep2.binary_ops[newTest.right.operator] <= 0.9) { + newTest = newTest.right; + } + env.node.test = newTest.right; + newTest.right = env.node; + env.node = test; + } + } else { + this.throwError("Expected :"); + } + } + }); + } +}; +jsep.plugins.register(ternary); +var FSLASH_CODE = 47; +var BSLASH_CODE = 92; +var index = { + name: "regex", + init(jsep2) { + jsep2.hooks.add("gobble-token", function gobbleRegexLiteral(env) { + if (this.code === FSLASH_CODE) { + const patternIndex = ++this.index; + let inCharSet = false; + while (this.index < this.expr.length) { + if (this.code === FSLASH_CODE && !inCharSet) { + const pattern = this.expr.slice(patternIndex, this.index); + let flags = ""; + while (++this.index < this.expr.length) { + const code = this.code; + if (code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57) { + flags += this.char; + } else { + break; + } + } + let value; + try { + value = new RegExp(pattern, flags); + } catch (e) { + this.throwError(e.message); + } + env.node = { + type: jsep2.LITERAL, + value, + raw: this.expr.slice(patternIndex - 1, this.index) + }; + env.node = this.gobbleTokenProperty(env.node); + return env.node; + } + if (this.code === jsep2.OBRACK_CODE) { + inCharSet = true; + } else if (inCharSet && this.code === jsep2.CBRACK_CODE) { + inCharSet = false; + } + this.index += this.code === BSLASH_CODE ? 2 : 1; + } + this.throwError("Unclosed Regex"); + } + }); + } +}; +var PLUS_CODE = 43; +var MINUS_CODE = 45; +var plugin = { + name: "assignment", + assignmentOperators: /* @__PURE__ */ new Set(["=", "*=", "**=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=", "^=", "|=", "||=", "&&=", "??="]), + updateOperators: [PLUS_CODE, MINUS_CODE], + assignmentPrecedence: 0.9, + init(jsep2) { + const updateNodeTypes = [jsep2.IDENTIFIER, jsep2.MEMBER_EXP]; + plugin.assignmentOperators.forEach((op) => jsep2.addBinaryOp(op, plugin.assignmentPrecedence, true)); + jsep2.hooks.add("gobble-token", function gobbleUpdatePrefix(env) { + const code = this.code; + if (plugin.updateOperators.some((c) => c === code && c === this.expr.charCodeAt(this.index + 1))) { + this.index += 2; + env.node = { + type: "UpdateExpression", + operator: code === PLUS_CODE ? "++" : "--", + argument: this.gobbleTokenProperty(this.gobbleIdentifier()), + prefix: true + }; + if (!env.node.argument || !updateNodeTypes.includes(env.node.argument.type)) { + this.throwError(`Unexpected ${env.node.operator}`); + } + } + }); + jsep2.hooks.add("after-token", function gobbleUpdatePostfix(env) { + if (env.node) { + const code = this.code; + if (plugin.updateOperators.some((c) => c === code && c === this.expr.charCodeAt(this.index + 1))) { + if (!updateNodeTypes.includes(env.node.type)) { + this.throwError(`Unexpected ${env.node.operator}`); + } + this.index += 2; + env.node = { + type: "UpdateExpression", + operator: code === PLUS_CODE ? "++" : "--", + argument: env.node, + prefix: false + }; + } + } + }); + jsep2.hooks.add("after-expression", function gobbleAssignment(env) { + if (env.node) { + updateBinariesToAssignments(env.node); + } + }); + function updateBinariesToAssignments(node) { + if (plugin.assignmentOperators.has(node.operator)) { + node.type = "AssignmentExpression"; + updateBinariesToAssignments(node.left); + updateBinariesToAssignments(node.right); + } else if (!node.operator) { + Object.values(node).forEach((val) => { + if (val && typeof val === "object") { + updateBinariesToAssignments(val); + } + }); + } + } + } +}; +jsep.plugins.register(index, plugin); +jsep.addUnaryOp("typeof"); +jsep.addLiteral("null", null); +jsep.addLiteral("undefined", void 0); +var BLOCKED_PROTO_PROPERTIES = /* @__PURE__ */ new Set(["constructor", "__proto__", "__defineGetter__", "__defineSetter__"]); +var SafeEval = { + /** + * @param {jsep.Expression} ast + * @param {Record} subs + */ + evalAst(ast, subs) { + switch (ast.type) { + case "BinaryExpression": + case "LogicalExpression": + return SafeEval.evalBinaryExpression(ast, subs); + case "Compound": + return SafeEval.evalCompound(ast, subs); + case "ConditionalExpression": + return SafeEval.evalConditionalExpression(ast, subs); + case "Identifier": + return SafeEval.evalIdentifier(ast, subs); + case "Literal": + return SafeEval.evalLiteral(ast, subs); + case "MemberExpression": + return SafeEval.evalMemberExpression(ast, subs); + case "UnaryExpression": + return SafeEval.evalUnaryExpression(ast, subs); + case "ArrayExpression": + return SafeEval.evalArrayExpression(ast, subs); + case "CallExpression": + return SafeEval.evalCallExpression(ast, subs); + case "AssignmentExpression": + return SafeEval.evalAssignmentExpression(ast, subs); + default: + throw SyntaxError("Unexpected expression", ast); + } + }, + evalBinaryExpression(ast, subs) { + const result = { + "||": (a, b) => a || b(), + "&&": (a, b) => a && b(), + "|": (a, b) => a | b(), + "^": (a, b) => a ^ b(), + "&": (a, b) => a & b(), + // eslint-disable-next-line eqeqeq -- API + "==": (a, b) => a == b(), + // eslint-disable-next-line eqeqeq -- API + "!=": (a, b) => a != b(), + "===": (a, b) => a === b(), + "!==": (a, b) => a !== b(), + "<": (a, b) => a < b(), + ">": (a, b) => a > b(), + "<=": (a, b) => a <= b(), + ">=": (a, b) => a >= b(), + "<<": (a, b) => a << b(), + ">>": (a, b) => a >> b(), + ">>>": (a, b) => a >>> b(), + "+": (a, b) => a + b(), + "-": (a, b) => a - b(), + "*": (a, b) => a * b(), + "/": (a, b) => a / b(), + "%": (a, b) => a % b() + }[ast.operator](SafeEval.evalAst(ast.left, subs), () => SafeEval.evalAst(ast.right, subs)); + return result; + }, + evalCompound(ast, subs) { + let last; + for (let i = 0; i < ast.body.length; i++) { + if (ast.body[i].type === "Identifier" && ["var", "let", "const"].includes(ast.body[i].name) && ast.body[i + 1] && ast.body[i + 1].type === "AssignmentExpression") { + i += 1; + } + const expr = ast.body[i]; + last = SafeEval.evalAst(expr, subs); + } + return last; + }, + evalConditionalExpression(ast, subs) { + if (SafeEval.evalAst(ast.test, subs)) { + return SafeEval.evalAst(ast.consequent, subs); + } + return SafeEval.evalAst(ast.alternate, subs); + }, + evalIdentifier(ast, subs) { + if (Object.hasOwn(subs, ast.name)) { + return subs[ast.name]; + } + throw ReferenceError(`${ast.name} is not defined`); + }, + evalLiteral(ast) { + return ast.value; + }, + evalMemberExpression(ast, subs) { + const prop = String( + // NOTE: `String(value)` throws error when + // value has overwritten the toString method to return non-string + // i.e. `value = {toString: () => []}` + ast.computed ? SafeEval.evalAst(ast.property) : ast.property.name + // `object.property` property is Identifier + ); + const obj = SafeEval.evalAst(ast.object, subs); + if (obj === void 0 || obj === null) { + throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`); + } + if (!Object.hasOwn(obj, prop) && BLOCKED_PROTO_PROPERTIES.has(prop)) { + throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`); + } + const result = obj[prop]; + if (typeof result === "function") { + return result.bind(obj); + } + return result; + }, + evalUnaryExpression(ast, subs) { + const result = { + "-": (a) => -SafeEval.evalAst(a, subs), + "!": (a) => !SafeEval.evalAst(a, subs), + "~": (a) => ~SafeEval.evalAst(a, subs), + // eslint-disable-next-line no-implicit-coercion -- API + "+": (a) => +SafeEval.evalAst(a, subs), + typeof: (a) => typeof SafeEval.evalAst(a, subs) + }[ast.operator](ast.argument); + return result; + }, + evalArrayExpression(ast, subs) { + return ast.elements.map((el) => SafeEval.evalAst(el, subs)); + }, + evalCallExpression(ast, subs) { + const args = ast.arguments.map((arg) => SafeEval.evalAst(arg, subs)); + const func = SafeEval.evalAst(ast.callee, subs); + return func(...args); + }, + evalAssignmentExpression(ast, subs) { + if (ast.left.type !== "Identifier") { + throw SyntaxError("Invalid left-hand side in assignment"); + } + const id = ast.left.name; + const value = SafeEval.evalAst(ast.right, subs); + subs[id] = value; + return subs[id]; + } +}; +var SafeScript = class { + /** + * @param {string} expr Expression to evaluate + */ + constructor(expr) { + this.code = expr; + this.ast = jsep(this.code); + } + /** + * @param {object} context Object whose items will be added + * to evaluation + * @returns {EvaluatedResult} Result of evaluated code + */ + runInNewContext(context) { + const keyMap = Object.assign(/* @__PURE__ */ Object.create(null), context); + return SafeEval.evalAst(this.ast, keyMap); + } +}; +function push(arr, item) { + arr = arr.slice(); + arr.push(item); + return arr; +} +function unshift(item, arr) { + arr = arr.slice(); + arr.unshift(item); + return arr; +} +var NewError = class extends Error { + /** + * @param {AnyResult} value The evaluated scalar value + */ + constructor(value) { + super('JSONPath should not be called with "new" (it prevents return of (unwrapped) scalar values)'); + this.avoidNew = true; + this.value = value; + this.name = "NewError"; + } +}; +function JSONPath(opts, expr, obj, callback, otherTypeCallback) { + if (!(this instanceof JSONPath)) { + try { + return new JSONPath(opts, expr, obj, callback, otherTypeCallback); + } catch (e) { + if (!e.avoidNew) { + throw e; + } + return e.value; + } + } + if (typeof opts === "string") { + otherTypeCallback = callback; + callback = obj; + obj = expr; + expr = opts; + opts = null; + } + const optObj = opts && typeof opts === "object"; + opts = opts || {}; + this.json = opts.json || obj; + this.path = opts.path || expr; + this.resultType = opts.resultType || "value"; + this.flatten = opts.flatten || false; + this.wrap = Object.hasOwn(opts, "wrap") ? opts.wrap : true; + this.sandbox = opts.sandbox || {}; + this.eval = opts.eval === void 0 ? "safe" : opts.eval; + this.ignoreEvalErrors = typeof opts.ignoreEvalErrors === "undefined" ? false : opts.ignoreEvalErrors; + this.parent = opts.parent || null; + this.parentProperty = opts.parentProperty || null; + this.callback = opts.callback || callback || null; + this.otherTypeCallback = opts.otherTypeCallback || otherTypeCallback || function() { + throw new TypeError("You must supply an otherTypeCallback callback option with the @other() operator."); + }; + if (opts.autostart !== false) { + const args = { + path: optObj ? opts.path : expr + }; + if (!optObj) { + args.json = obj; + } else if ("json" in opts) { + args.json = opts.json; + } + const ret = this.evaluate(args); + if (!ret || typeof ret !== "object") { + throw new NewError(ret); + } + return ret; + } +} +JSONPath.prototype.evaluate = function(expr, json, callback, otherTypeCallback) { + let currParent = this.parent, currParentProperty = this.parentProperty; + let { + flatten, + wrap + } = this; + this.currResultType = this.resultType; + this.currEval = this.eval; + this.currSandbox = this.sandbox; + callback = callback || this.callback; + this.currOtherTypeCallback = otherTypeCallback || this.otherTypeCallback; + json = json || this.json; + expr = expr || this.path; + if (expr && typeof expr === "object" && !Array.isArray(expr)) { + if (!expr.path && expr.path !== "") { + throw new TypeError('You must supply a "path" property when providing an object argument to JSONPath.evaluate().'); + } + if (!Object.hasOwn(expr, "json")) { + throw new TypeError('You must supply a "json" property when providing an object argument to JSONPath.evaluate().'); + } + ({ + json + } = expr); + flatten = Object.hasOwn(expr, "flatten") ? expr.flatten : flatten; + this.currResultType = Object.hasOwn(expr, "resultType") ? expr.resultType : this.currResultType; + this.currSandbox = Object.hasOwn(expr, "sandbox") ? expr.sandbox : this.currSandbox; + wrap = Object.hasOwn(expr, "wrap") ? expr.wrap : wrap; + this.currEval = Object.hasOwn(expr, "eval") ? expr.eval : this.currEval; + callback = Object.hasOwn(expr, "callback") ? expr.callback : callback; + this.currOtherTypeCallback = Object.hasOwn(expr, "otherTypeCallback") ? expr.otherTypeCallback : this.currOtherTypeCallback; + currParent = Object.hasOwn(expr, "parent") ? expr.parent : currParent; + currParentProperty = Object.hasOwn(expr, "parentProperty") ? expr.parentProperty : currParentProperty; + expr = expr.path; + } + currParent = currParent || null; + currParentProperty = currParentProperty || null; + if (Array.isArray(expr)) { + expr = JSONPath.toPathString(expr); + } + if (!expr && expr !== "" || !json) { + return void 0; + } + const exprList = JSONPath.toPathArray(expr); + if (exprList[0] === "$" && exprList.length > 1) { + exprList.shift(); + } + this._hasParentSelector = null; + const result = this._trace(exprList, json, ["$"], currParent, currParentProperty, callback).filter(function(ea) { + return ea && !ea.isParentSelector; + }); + if (!result.length) { + return wrap ? [] : void 0; + } + if (!wrap && result.length === 1 && !result[0].hasArrExpr) { + return this._getPreferredOutput(result[0]); + } + return result.reduce((rslt, ea) => { + const valOrPath = this._getPreferredOutput(ea); + if (flatten && Array.isArray(valOrPath)) { + rslt = rslt.concat(valOrPath); + } else { + rslt.push(valOrPath); + } + return rslt; + }, []); +}; +JSONPath.prototype._getPreferredOutput = function(ea) { + const resultType = this.currResultType; + switch (resultType) { + case "all": { + const path = Array.isArray(ea.path) ? ea.path : JSONPath.toPathArray(ea.path); + ea.pointer = JSONPath.toPointer(path); + ea.path = typeof ea.path === "string" ? ea.path : JSONPath.toPathString(ea.path); + return ea; + } + case "value": + case "parent": + case "parentProperty": + return ea[resultType]; + case "path": + return JSONPath.toPathString(ea[resultType]); + case "pointer": + return JSONPath.toPointer(ea.path); + default: + throw new TypeError("Unknown result type"); + } +}; +JSONPath.prototype._handleCallback = function(fullRetObj, callback, type) { + if (callback) { + const preferredOutput = this._getPreferredOutput(fullRetObj); + fullRetObj.path = typeof fullRetObj.path === "string" ? fullRetObj.path : JSONPath.toPathString(fullRetObj.path); + callback(preferredOutput, type, fullRetObj); + } +}; +JSONPath.prototype._trace = function(expr, val, path, parent, parentPropName, callback, hasArrExpr, literalPriority) { + let retObj; + if (!expr.length) { + retObj = { + path, + value: val, + parent, + parentProperty: parentPropName, + hasArrExpr + }; + this._handleCallback(retObj, callback, "value"); + return retObj; + } + const loc = expr[0], x = expr.slice(1); + const ret = []; + function addRet(elems) { + if (Array.isArray(elems)) { + elems.forEach((t) => { + ret.push(t); + }); + } else { + ret.push(elems); + } + } + if ((typeof loc !== "string" || literalPriority) && val && Object.hasOwn(val, loc)) { + addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr)); + } else if (loc === "*") { + this._walk(val, (m) => { + addRet(this._trace(x, val[m], push(path, m), val, m, callback, true, true)); + }); + } else if (loc === "..") { + addRet(this._trace(x, val, path, parent, parentPropName, callback, hasArrExpr)); + this._walk(val, (m) => { + if (typeof val[m] === "object") { + addRet(this._trace(expr.slice(), val[m], push(path, m), val, m, callback, true)); + } + }); + } else if (loc === "^") { + this._hasParentSelector = true; + return { + path: path.slice(0, -1), + expr: x, + isParentSelector: true + }; + } else if (loc === "~") { + retObj = { + path: push(path, loc), + value: parentPropName, + parent, + parentProperty: null + }; + this._handleCallback(retObj, callback, "property"); + return retObj; + } else if (loc === "$") { + addRet(this._trace(x, val, path, null, null, callback, hasArrExpr)); + } else if (/^(-?\d*):(-?\d*):?(\d*)$/u.test(loc)) { + addRet(this._slice(loc, x, val, path, parent, parentPropName, callback)); + } else if (loc.indexOf("?(") === 0) { + if (this.currEval === false) { + throw new Error("Eval [?(expr)] prevented in JSONPath expression."); + } + const safeLoc = loc.replace(/^\?\((.*?)\)$/u, "$1"); + const nested = /@.?([^?]*)[['](\??\(.*?\))(?!.\)\])[\]']/gu.exec(safeLoc); + if (nested) { + this._walk(val, (m) => { + const npath = [nested[2]]; + const nvalue = nested[1] ? val[m][nested[1]] : val[m]; + const filterResults = this._trace(npath, nvalue, path, parent, parentPropName, callback, true); + if (filterResults.length > 0) { + addRet(this._trace(x, val[m], push(path, m), val, m, callback, true)); + } + }); + } else { + this._walk(val, (m) => { + if (this._eval(safeLoc, val[m], m, path, parent, parentPropName)) { + addRet(this._trace(x, val[m], push(path, m), val, m, callback, true)); + } + }); + } + } else if (loc[0] === "(") { + if (this.currEval === false) { + throw new Error("Eval [(expr)] prevented in JSONPath expression."); + } + addRet(this._trace(unshift(this._eval(loc, val, path.at(-1), path.slice(0, -1), parent, parentPropName), x), val, path, parent, parentPropName, callback, hasArrExpr)); + } else if (loc[0] === "@") { + let addType = false; + const valueType = loc.slice(1, -2); + switch (valueType) { + case "scalar": + if (!val || !["object", "function"].includes(typeof val)) { + addType = true; + } + break; + case "boolean": + case "string": + case "undefined": + case "function": + if (typeof val === valueType) { + addType = true; + } + break; + case "integer": + if (Number.isFinite(val) && !(val % 1)) { + addType = true; + } + break; + case "number": + if (Number.isFinite(val)) { + addType = true; + } + break; + case "nonFinite": + if (typeof val === "number" && !Number.isFinite(val)) { + addType = true; + } + break; + case "object": + if (val && typeof val === valueType) { + addType = true; + } + break; + case "array": + if (Array.isArray(val)) { + addType = true; + } + break; + case "other": + addType = this.currOtherTypeCallback(val, path, parent, parentPropName); + break; + case "null": + if (val === null) { + addType = true; + } + break; + default: + throw new TypeError("Unknown value type " + valueType); + } + if (addType) { + retObj = { + path, + value: val, + parent, + parentProperty: parentPropName + }; + this._handleCallback(retObj, callback, "value"); + return retObj; + } + } else if (loc[0] === "`" && val && Object.hasOwn(val, loc.slice(1))) { + const locProp = loc.slice(1); + addRet(this._trace(x, val[locProp], push(path, locProp), val, locProp, callback, hasArrExpr, true)); + } else if (loc.includes(",")) { + const parts = loc.split(","); + for (const part of parts) { + addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback, true)); + } + } else if (!literalPriority && val && Object.hasOwn(val, loc)) { + addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr, true)); + } + if (this._hasParentSelector) { + for (let t = 0; t < ret.length; t++) { + const rett = ret[t]; + if (rett && rett.isParentSelector) { + const tmp = this._trace(rett.expr, val, rett.path, parent, parentPropName, callback, hasArrExpr); + if (Array.isArray(tmp)) { + ret[t] = tmp[0]; + const tl = tmp.length; + for (let tt = 1; tt < tl; tt++) { + t++; + ret.splice(t, 0, tmp[tt]); + } + } else { + ret[t] = tmp; + } + } + } + } + return ret; +}; +JSONPath.prototype._walk = function(val, f) { + if (Array.isArray(val)) { + const n = val.length; + for (let i = 0; i < n; i++) { + f(i); + } + } else if (val && typeof val === "object") { + Object.keys(val).forEach((m) => { + f(m); + }); + } +}; +JSONPath.prototype._slice = function(loc, expr, val, path, parent, parentPropName, callback) { + if (!Array.isArray(val)) { + return void 0; + } + const len = val.length, parts = loc.split(":"), step = parts[2] && Number.parseInt(parts[2]) || 1; + let start = parts[0] && Number.parseInt(parts[0]) || 0, end = parts[1] && Number.parseInt(parts[1]) || len; + start = start < 0 ? Math.max(0, start + len) : Math.min(len, start); + end = end < 0 ? Math.max(0, end + len) : Math.min(len, end); + const ret = []; + for (let i = start; i < end; i += step) { + const tmp = this._trace(unshift(i, expr), val, path, parent, parentPropName, callback, true); + tmp.forEach((t) => { + ret.push(t); + }); + } + return ret; +}; +JSONPath.prototype._eval = function(code, _v, _vname, path, parent, parentPropName) { + this.currSandbox._$_parentProperty = parentPropName; + this.currSandbox._$_parent = parent; + this.currSandbox._$_property = _vname; + this.currSandbox._$_root = this.json; + this.currSandbox._$_v = _v; + const containsPath = code.includes("@path"); + if (containsPath) { + this.currSandbox._$_path = JSONPath.toPathString(path.concat([_vname])); + } + const scriptCacheKey = this.currEval + "Script:" + code; + if (!JSONPath.cache[scriptCacheKey]) { + let script = code.replaceAll("@parentProperty", "_$_parentProperty").replaceAll("@parent", "_$_parent").replaceAll("@property", "_$_property").replaceAll("@root", "_$_root").replaceAll(/@([.\s)[])/gu, "_$_v$1"); + if (containsPath) { + script = script.replaceAll("@path", "_$_path"); + } + if (this.currEval === "safe" || this.currEval === true || this.currEval === void 0) { + JSONPath.cache[scriptCacheKey] = new this.safeVm.Script(script); + } else if (this.currEval === "native") { + JSONPath.cache[scriptCacheKey] = new this.vm.Script(script); + } else if (typeof this.currEval === "function" && this.currEval.prototype && Object.hasOwn(this.currEval.prototype, "runInNewContext")) { + const CurrEval = this.currEval; + JSONPath.cache[scriptCacheKey] = new CurrEval(script); + } else if (typeof this.currEval === "function") { + JSONPath.cache[scriptCacheKey] = { + runInNewContext: (context) => this.currEval(script, context) + }; + } else { + throw new TypeError(`Unknown "eval" property "${this.currEval}"`); + } + } + try { + return JSONPath.cache[scriptCacheKey].runInNewContext(this.currSandbox); + } catch (e) { + if (this.ignoreEvalErrors) { + return false; + } + throw new Error("jsonPath: " + e.message + ": " + code); + } +}; +JSONPath.cache = {}; +JSONPath.toPathString = function(pathArr) { + const x = pathArr, n = x.length; + let p = "$"; + for (let i = 1; i < n; i++) { + if (!/^(~|\^|@.*?\(\))$/u.test(x[i])) { + p += /^[0-9*]+$/u.test(x[i]) ? "[" + x[i] + "]" : "['" + x[i] + "']"; + } + } + return p; +}; +JSONPath.toPointer = function(pointer) { + const x = pointer, n = x.length; + let p = ""; + for (let i = 1; i < n; i++) { + if (!/^(~|\^|@.*?\(\))$/u.test(x[i])) { + p += "/" + x[i].toString().replaceAll("~", "~0").replaceAll("/", "~1"); + } + } + return p; +}; +JSONPath.toPathArray = function(expr) { + const { + cache + } = JSONPath; + if (cache[expr]) { + return cache[expr].concat(); + } + const subx = []; + const normalized = expr.replaceAll(/@(?:null|boolean|number|string|integer|undefined|nonFinite|scalar|array|object|function|other)\(\)/gu, ";$&;").replaceAll(/[['](\??\(.*?\))[\]'](?!.\])/gu, function($0, $1) { + return "[#" + (subx.push($1) - 1) + "]"; + }).replaceAll(/\[['"]([^'\]]*)['"]\]/gu, function($0, prop) { + return "['" + prop.replaceAll(".", "%@%").replaceAll("~", "%%@@%%") + "']"; + }).replaceAll("~", ";~;").replaceAll(/['"]?\.['"]?(?![^[]*\])|\[['"]?/gu, ";").replaceAll("%@%", ".").replaceAll("%%@@%%", "~").replaceAll(/(?:;)?(\^+)(?:;)?/gu, function($0, ups) { + return ";" + ups.split("").join(";") + ";"; + }).replaceAll(/;;;|;;/gu, ";..;").replaceAll(/;$|'?\]|'$/gu, ""); + const exprList = normalized.split(";").map(function(exp) { + const match = exp.match(/#(\d+)/u); + return !match || !match[1] ? exp : subx[match[1]]; + }); + cache[expr] = exprList; + return cache[expr].concat(); +}; +JSONPath.prototype.safeVm = { + Script: SafeScript +}; +JSONPath.prototype.vm = import_vm.default; + +// src/index.ts +var plugin2 = { + templateFunctions: [ + { + name: "json.jsonpath", + description: "Filter JSON-formatted text using JSONPath syntax", + args: [ + { type: "text", name: "input", label: "Input", multiLine: true, placeholder: '{ "foo": "bar" }' }, + { type: "text", name: "query", label: "Query", placeholder: "$..foo" }, + { type: "checkbox", name: "formatted", label: "Format Output" } + ], + async onRender(_ctx, args) { + try { + const parsed = JSON.parse(String(args.values.input)); + const query = String(args.values.query ?? "$").trim(); + let filtered = JSONPath({ path: query, json: parsed }); + if (Array.isArray(filtered)) { + filtered = filtered[0]; + } + if (args.values.formatted) { + return JSON.stringify(filtered, null, 2); + } else { + return JSON.stringify(filtered); + } + } catch (e) { + return null; + } + } + }, + { + name: "json.escape", + description: "Escape a JSON string, useful when using the output in JSON values", + args: [ + { type: "text", name: "input", label: "Input", multiLine: true, placeholder: 'Hello "World"' } + ], + async onRender(_ctx, args) { + const input = String(args.values.input ?? ""); + return input.replace(/\\/g, "\\\\").replace(/"/g, '\\"'); + } + } + ] +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + plugin +}); diff --git a/src-tauri/vendored/plugins/template-function-json/package.json b/src-tauri/vendored/plugins/template-function-json/package.json new file mode 100755 index 000000000..b18f1a9ad --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-json/package.json @@ -0,0 +1,15 @@ +{ + "name": "@yaakapp/template-function-json", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + }, + "dependencies": { + "jsonpath-plus": "^10.3.0" + }, + "devDependencies": { + "@types/jsonpath": "^0.2.4" + } +} diff --git a/src-tauri/vendored/plugins/template-function-uuid/build/index.js b/src-tauri/vendored/plugins/template-function-uuid/build/index.js new file mode 100644 index 000000000..915c7e30c --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-uuid/build/index.js @@ -0,0 +1,417 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var src_exports = {}; +__export(src_exports, { + plugin: () => plugin +}); +module.exports = __toCommonJS(src_exports); + +// node_modules/uuid/dist/esm/regex.js +var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i; + +// node_modules/uuid/dist/esm/validate.js +function validate(uuid) { + return typeof uuid === "string" && regex_default.test(uuid); +} +var validate_default = validate; + +// node_modules/uuid/dist/esm/parse.js +function parse(uuid) { + if (!validate_default(uuid)) { + throw TypeError("Invalid UUID"); + } + let v; + return Uint8Array.of((v = parseInt(uuid.slice(0, 8), 16)) >>> 24, v >>> 16 & 255, v >>> 8 & 255, v & 255, (v = parseInt(uuid.slice(9, 13), 16)) >>> 8, v & 255, (v = parseInt(uuid.slice(14, 18), 16)) >>> 8, v & 255, (v = parseInt(uuid.slice(19, 23), 16)) >>> 8, v & 255, (v = parseInt(uuid.slice(24, 36), 16)) / 1099511627776 & 255, v / 4294967296 & 255, v >>> 24 & 255, v >>> 16 & 255, v >>> 8 & 255, v & 255); +} +var parse_default = parse; + +// node_modules/uuid/dist/esm/stringify.js +var byteToHex = []; +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 256).toString(16).slice(1)); +} +function unsafeStringify(arr, offset = 0) { + return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); +} + +// node_modules/uuid/dist/esm/rng.js +var import_crypto = require("crypto"); +var rnds8Pool = new Uint8Array(256); +var poolPtr = rnds8Pool.length; +function rng() { + if (poolPtr > rnds8Pool.length - 16) { + (0, import_crypto.randomFillSync)(rnds8Pool); + poolPtr = 0; + } + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} + +// node_modules/uuid/dist/esm/v1.js +var _state = {}; +function v1(options, buf, offset) { + let bytes; + const isV6 = options?._v6 ?? false; + if (options) { + const optionsKeys = Object.keys(options); + if (optionsKeys.length === 1 && optionsKeys[0] === "_v6") { + options = void 0; + } + } + if (options) { + bytes = v1Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.nsecs, options.clockseq, options.node, buf, offset); + } else { + const now = Date.now(); + const rnds = rng(); + updateV1State(_state, now, rnds); + bytes = v1Bytes(rnds, _state.msecs, _state.nsecs, isV6 ? void 0 : _state.clockseq, isV6 ? void 0 : _state.node, buf, offset); + } + return buf ?? unsafeStringify(bytes); +} +function updateV1State(state, now, rnds) { + state.msecs ??= -Infinity; + state.nsecs ??= 0; + if (now === state.msecs) { + state.nsecs++; + if (state.nsecs >= 1e4) { + state.node = void 0; + state.nsecs = 0; + } + } else if (now > state.msecs) { + state.nsecs = 0; + } else if (now < state.msecs) { + state.node = void 0; + } + if (!state.node) { + state.node = rnds.slice(10, 16); + state.node[0] |= 1; + state.clockseq = (rnds[8] << 8 | rnds[9]) & 16383; + } + state.msecs = now; + return state; +} +function v1Bytes(rnds, msecs, nsecs, clockseq, node, buf, offset = 0) { + if (rnds.length < 16) { + throw new Error("Random bytes length must be >= 16"); + } + if (!buf) { + buf = new Uint8Array(16); + offset = 0; + } else { + if (offset < 0 || offset + 16 > buf.length) { + throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`); + } + } + msecs ??= Date.now(); + nsecs ??= 0; + clockseq ??= (rnds[8] << 8 | rnds[9]) & 16383; + node ??= rnds.slice(10, 16); + msecs += 122192928e5; + const tl = ((msecs & 268435455) * 1e4 + nsecs) % 4294967296; + buf[offset++] = tl >>> 24 & 255; + buf[offset++] = tl >>> 16 & 255; + buf[offset++] = tl >>> 8 & 255; + buf[offset++] = tl & 255; + const tmh = msecs / 4294967296 * 1e4 & 268435455; + buf[offset++] = tmh >>> 8 & 255; + buf[offset++] = tmh & 255; + buf[offset++] = tmh >>> 24 & 15 | 16; + buf[offset++] = tmh >>> 16 & 255; + buf[offset++] = clockseq >>> 8 | 128; + buf[offset++] = clockseq & 255; + for (let n = 0; n < 6; ++n) { + buf[offset++] = node[n]; + } + return buf; +} +var v1_default = v1; + +// node_modules/uuid/dist/esm/v1ToV6.js +function v1ToV6(uuid) { + const v1Bytes2 = typeof uuid === "string" ? parse_default(uuid) : uuid; + const v6Bytes = _v1ToV6(v1Bytes2); + return typeof uuid === "string" ? unsafeStringify(v6Bytes) : v6Bytes; +} +function _v1ToV6(v1Bytes2) { + return Uint8Array.of((v1Bytes2[6] & 15) << 4 | v1Bytes2[7] >> 4 & 15, (v1Bytes2[7] & 15) << 4 | (v1Bytes2[4] & 240) >> 4, (v1Bytes2[4] & 15) << 4 | (v1Bytes2[5] & 240) >> 4, (v1Bytes2[5] & 15) << 4 | (v1Bytes2[0] & 240) >> 4, (v1Bytes2[0] & 15) << 4 | (v1Bytes2[1] & 240) >> 4, (v1Bytes2[1] & 15) << 4 | (v1Bytes2[2] & 240) >> 4, 96 | v1Bytes2[2] & 15, v1Bytes2[3], v1Bytes2[8], v1Bytes2[9], v1Bytes2[10], v1Bytes2[11], v1Bytes2[12], v1Bytes2[13], v1Bytes2[14], v1Bytes2[15]); +} + +// node_modules/uuid/dist/esm/md5.js +var import_crypto2 = require("crypto"); +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === "string") { + bytes = Buffer.from(bytes, "utf8"); + } + return (0, import_crypto2.createHash)("md5").update(bytes).digest(); +} +var md5_default = md5; + +// node_modules/uuid/dist/esm/v35.js +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); + const bytes = new Uint8Array(str.length); + for (let i = 0; i < str.length; ++i) { + bytes[i] = str.charCodeAt(i); + } + return bytes; +} +var DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; +var URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; +function v35(version, hash, value, namespace, buf, offset) { + const valueBytes = typeof value === "string" ? stringToBytes(value) : value; + const namespaceBytes = typeof namespace === "string" ? parse_default(namespace) : namespace; + if (typeof namespace === "string") { + namespace = parse_default(namespace); + } + if (namespace?.length !== 16) { + throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)"); + } + let bytes = new Uint8Array(16 + valueBytes.length); + bytes.set(namespaceBytes); + bytes.set(valueBytes, namespaceBytes.length); + bytes = hash(bytes); + bytes[6] = bytes[6] & 15 | version; + bytes[8] = bytes[8] & 63 | 128; + if (buf) { + offset = offset || 0; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + return buf; + } + return unsafeStringify(bytes); +} + +// node_modules/uuid/dist/esm/v3.js +function v3(value, namespace, buf, offset) { + return v35(48, md5_default, value, namespace, buf, offset); +} +v3.DNS = DNS; +v3.URL = URL; +var v3_default = v3; + +// node_modules/uuid/dist/esm/native.js +var import_crypto3 = require("crypto"); +var native_default = { randomUUID: import_crypto3.randomUUID }; + +// node_modules/uuid/dist/esm/v4.js +function v4(options, buf, offset) { + if (native_default.randomUUID && !buf && !options) { + return native_default.randomUUID(); + } + options = options || {}; + const rnds = options.random ?? options.rng?.() ?? rng(); + if (rnds.length < 16) { + throw new Error("Random bytes length must be >= 16"); + } + rnds[6] = rnds[6] & 15 | 64; + rnds[8] = rnds[8] & 63 | 128; + if (buf) { + offset = offset || 0; + if (offset < 0 || offset + 16 > buf.length) { + throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`); + } + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + return buf; + } + return unsafeStringify(rnds); +} +var v4_default = v4; + +// node_modules/uuid/dist/esm/sha1.js +var import_crypto4 = require("crypto"); +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === "string") { + bytes = Buffer.from(bytes, "utf8"); + } + return (0, import_crypto4.createHash)("sha1").update(bytes).digest(); +} +var sha1_default = sha1; + +// node_modules/uuid/dist/esm/v5.js +function v5(value, namespace, buf, offset) { + return v35(80, sha1_default, value, namespace, buf, offset); +} +v5.DNS = DNS; +v5.URL = URL; +var v5_default = v5; + +// node_modules/uuid/dist/esm/v6.js +function v6(options, buf, offset) { + options ??= {}; + offset ??= 0; + let bytes = v1_default({ ...options, _v6: true }, new Uint8Array(16)); + bytes = v1ToV6(bytes); + if (buf) { + for (let i = 0; i < 16; i++) { + buf[offset + i] = bytes[i]; + } + return buf; + } + return unsafeStringify(bytes); +} +var v6_default = v6; + +// node_modules/uuid/dist/esm/v7.js +var _state2 = {}; +function v7(options, buf, offset) { + let bytes; + if (options) { + bytes = v7Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.seq, buf, offset); + } else { + const now = Date.now(); + const rnds = rng(); + updateV7State(_state2, now, rnds); + bytes = v7Bytes(rnds, _state2.msecs, _state2.seq, buf, offset); + } + return buf ?? unsafeStringify(bytes); +} +function updateV7State(state, now, rnds) { + state.msecs ??= -Infinity; + state.seq ??= 0; + if (now > state.msecs) { + state.seq = rnds[6] << 23 | rnds[7] << 16 | rnds[8] << 8 | rnds[9]; + state.msecs = now; + } else { + state.seq = state.seq + 1 | 0; + if (state.seq === 0) { + state.msecs++; + } + } + return state; +} +function v7Bytes(rnds, msecs, seq, buf, offset = 0) { + if (rnds.length < 16) { + throw new Error("Random bytes length must be >= 16"); + } + if (!buf) { + buf = new Uint8Array(16); + offset = 0; + } else { + if (offset < 0 || offset + 16 > buf.length) { + throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`); + } + } + msecs ??= Date.now(); + seq ??= rnds[6] * 127 << 24 | rnds[7] << 16 | rnds[8] << 8 | rnds[9]; + buf[offset++] = msecs / 1099511627776 & 255; + buf[offset++] = msecs / 4294967296 & 255; + buf[offset++] = msecs / 16777216 & 255; + buf[offset++] = msecs / 65536 & 255; + buf[offset++] = msecs / 256 & 255; + buf[offset++] = msecs & 255; + buf[offset++] = 112 | seq >>> 28 & 15; + buf[offset++] = seq >>> 20 & 255; + buf[offset++] = 128 | seq >>> 14 & 63; + buf[offset++] = seq >>> 6 & 255; + buf[offset++] = seq << 2 & 255 | rnds[10] & 3; + buf[offset++] = rnds[11]; + buf[offset++] = rnds[12]; + buf[offset++] = rnds[13]; + buf[offset++] = rnds[14]; + buf[offset++] = rnds[15]; + return buf; +} +var v7_default = v7; + +// src/index.ts +var plugin = { + templateFunctions: [ + { + name: "uuid.v1", + description: "Generate a UUID V1", + args: [], + async onRender(_ctx, _args) { + return v1_default(); + } + }, + { + name: "uuid.v3", + description: "Generate a UUID V3", + args: [ + { type: "text", name: "name", label: "Name" }, + { + type: "text", + name: "namespace", + label: "Namespace UUID", + description: "A valid UUID to use as the namespace", + placeholder: "24ced880-3bf4-11f0-8329-cd053d577f0e" + } + ], + async onRender(_ctx, args) { + return v3_default(String(args.values.name), String(args.values.namespace)); + } + }, + { + name: "uuid.v4", + description: "Generate a UUID V4", + args: [], + async onRender(_ctx, _args) { + return v4_default(); + } + }, + { + name: "uuid.v5", + description: "Generate a UUID V5", + args: [ + { type: "text", name: "name", label: "Name" }, + { type: "text", name: "namespace", label: "Namespace" } + ], + async onRender(_ctx, args) { + return v5_default(String(args.values.name), String(args.values.namespace)); + } + }, + { + name: "uuid.v6", + description: "Generate a UUID V6", + args: [ + { + type: "text", + name: "timestamp", + label: "Timestamp", + optional: true, + description: "Can be any format that can be parsed by JavaScript new Date(...)", + placeholder: "2025-05-28T11:15:00Z" + } + ], + async onRender(_ctx, args) { + return v6_default({ msecs: new Date(String(args.values.timestamp)).getTime() }); + } + }, + { + name: "uuid.v7", + description: "Generate a UUID V7", + args: [], + async onRender(_ctx, _args) { + return v7_default(); + } + } + ] +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + plugin +}); diff --git a/src-tauri/vendored/plugins/template-function-uuid/package.json b/src-tauri/vendored/plugins/template-function-uuid/package.json new file mode 100644 index 000000000..4b1538ead --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-uuid/package.json @@ -0,0 +1,12 @@ +{ + "name": "@yaakapp/template-function-uuid", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + }, + "dependencies": { + "uuid": "^11.1.0" + } +} diff --git a/src-tauri/vendored/plugins/template-function-xml/build/index.js b/src-tauri/vendored/plugins/template-function-xml/build/index.js new file mode 100644 index 000000000..1bdc3cef1 --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-xml/build/index.js @@ -0,0 +1,8380 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + for (var name2 in all) + __defProp(target, name2, { get: all[name2], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// ../../node_modules/@xmldom/xmldom/lib/conventions.js +var require_conventions = __commonJS({ + "../../node_modules/@xmldom/xmldom/lib/conventions.js"(exports2) { + "use strict"; + function find(list, predicate, ac) { + if (ac === void 0) { + ac = Array.prototype; + } + if (list && typeof ac.find === "function") { + return ac.find.call(list, predicate); + } + for (var i = 0; i < list.length; i++) { + if (Object.prototype.hasOwnProperty.call(list, i)) { + var item = list[i]; + if (predicate.call(void 0, item, i, list)) { + return item; + } + } + } + } + function freeze(object, oc) { + if (oc === void 0) { + oc = Object; + } + return oc && typeof oc.freeze === "function" ? oc.freeze(object) : object; + } + function assign(target, source) { + if (target === null || typeof target !== "object") { + throw new TypeError("target is not an object"); + } + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + return target; + } + var MIME_TYPE = freeze({ + /** + * `text/html`, the only mime type that triggers treating an XML document as HTML. + * + * @see DOMParser.SupportedType.isHTML + * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration + * @see https://en.wikipedia.org/wiki/HTML Wikipedia + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring WHATWG HTML Spec + */ + HTML: "text/html", + /** + * Helper method to check a mime type if it indicates an HTML document + * + * @param {string} [value] + * @returns {boolean} + * + * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration + * @see https://en.wikipedia.org/wiki/HTML Wikipedia + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring */ + isHTML: function(value) { + return value === MIME_TYPE.HTML; + }, + /** + * `application/xml`, the standard mime type for XML documents. + * + * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType registration + * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303 + * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia + */ + XML_APPLICATION: "application/xml", + /** + * `text/html`, an alias for `application/xml`. + * + * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303 + * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration + * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia + */ + XML_TEXT: "text/xml", + /** + * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace, + * but is parsed as an XML document. + * + * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType registration + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec + * @see https://en.wikipedia.org/wiki/XHTML Wikipedia + */ + XML_XHTML_APPLICATION: "application/xhtml+xml", + /** + * `image/svg+xml`, + * + * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration + * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1 + * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia + */ + XML_SVG_IMAGE: "image/svg+xml" + }); + var NAMESPACE = freeze({ + /** + * The XHTML namespace. + * + * @see http://www.w3.org/1999/xhtml + */ + HTML: "http://www.w3.org/1999/xhtml", + /** + * Checks if `uri` equals `NAMESPACE.HTML`. + * + * @param {string} [uri] + * + * @see NAMESPACE.HTML + */ + isHTML: function(uri) { + return uri === NAMESPACE.HTML; + }, + /** + * The SVG namespace. + * + * @see http://www.w3.org/2000/svg + */ + SVG: "http://www.w3.org/2000/svg", + /** + * The `xml:` namespace. + * + * @see http://www.w3.org/XML/1998/namespace + */ + XML: "http://www.w3.org/XML/1998/namespace", + /** + * The `xmlns:` namespace + * + * @see https://www.w3.org/2000/xmlns/ + */ + XMLNS: "http://www.w3.org/2000/xmlns/" + }); + exports2.assign = assign; + exports2.find = find; + exports2.freeze = freeze; + exports2.MIME_TYPE = MIME_TYPE; + exports2.NAMESPACE = NAMESPACE; + } +}); + +// ../../node_modules/@xmldom/xmldom/lib/dom.js +var require_dom = __commonJS({ + "../../node_modules/@xmldom/xmldom/lib/dom.js"(exports2) { + var conventions = require_conventions(); + var find = conventions.find; + var NAMESPACE = conventions.NAMESPACE; + function notEmptyString(input) { + return input !== ""; + } + function splitOnASCIIWhitespace(input) { + return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : []; + } + function orderedSetReducer(current, element) { + if (!current.hasOwnProperty(element)) { + current[element] = true; + } + return current; + } + function toOrderedSet(input) { + if (!input) return []; + var list = splitOnASCIIWhitespace(input); + return Object.keys(list.reduce(orderedSetReducer, {})); + } + function arrayIncludes(list) { + return function(element) { + return list && list.indexOf(element) !== -1; + }; + } + function copy(src, dest) { + for (var p in src) { + if (Object.prototype.hasOwnProperty.call(src, p)) { + dest[p] = src[p]; + } + } + } + function _extends(Class, Super) { + var pt = Class.prototype; + if (!(pt instanceof Super)) { + let t2 = function() { + }; + var t = t2; + ; + t2.prototype = Super.prototype; + t2 = new t2(); + copy(pt, t2); + Class.prototype = pt = t2; + } + if (pt.constructor != Class) { + if (typeof Class != "function") { + console.error("unknown Class:" + Class); + } + pt.constructor = Class; + } + } + var NodeType = {}; + var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1; + var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2; + var TEXT_NODE = NodeType.TEXT_NODE = 3; + var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4; + var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5; + var ENTITY_NODE = NodeType.ENTITY_NODE = 6; + var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7; + var COMMENT_NODE = NodeType.COMMENT_NODE = 8; + var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9; + var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10; + var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11; + var NOTATION_NODE = NodeType.NOTATION_NODE = 12; + var ExceptionCode = {}; + var ExceptionMessage = {}; + var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = (ExceptionMessage[1] = "Index size error", 1); + var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = (ExceptionMessage[2] = "DOMString size error", 2); + var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = (ExceptionMessage[3] = "Hierarchy request error", 3); + var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = (ExceptionMessage[4] = "Wrong document", 4); + var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = (ExceptionMessage[5] = "Invalid character", 5); + var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = (ExceptionMessage[6] = "No data allowed", 6); + var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = (ExceptionMessage[7] = "No modification allowed", 7); + var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = (ExceptionMessage[8] = "Not found", 8); + var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = (ExceptionMessage[9] = "Not supported", 9); + var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = (ExceptionMessage[10] = "Attribute in use", 10); + var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = (ExceptionMessage[11] = "Invalid state", 11); + var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = (ExceptionMessage[12] = "Syntax error", 12); + var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = (ExceptionMessage[13] = "Invalid modification", 13); + var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = (ExceptionMessage[14] = "Invalid namespace", 14); + var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = (ExceptionMessage[15] = "Invalid access", 15); + function DOMException(code, message) { + if (message instanceof Error) { + var error = message; + } else { + error = this; + Error.call(this, ExceptionMessage[code]); + this.message = ExceptionMessage[code]; + if (Error.captureStackTrace) Error.captureStackTrace(this, DOMException); + } + error.code = code; + if (message) this.message = this.message + ": " + message; + return error; + } + DOMException.prototype = Error.prototype; + copy(ExceptionCode, DOMException); + function NodeList() { + } + NodeList.prototype = { + /** + * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive. + * @standard level1 + */ + length: 0, + /** + * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null. + * @standard level1 + * @param index unsigned long + * Index into the collection. + * @return Node + * The node at the indexth position in the NodeList, or null if that is not a valid index. + */ + item: function(index) { + return index >= 0 && index < this.length ? this[index] : null; + }, + toString: function(isHTML, nodeFilter) { + for (var buf = [], i = 0; i < this.length; i++) { + serializeToString(this[i], buf, isHTML, nodeFilter); + } + return buf.join(""); + }, + /** + * @private + * @param {function (Node):boolean} predicate + * @returns {Node[]} + */ + filter: function(predicate) { + return Array.prototype.filter.call(this, predicate); + }, + /** + * @private + * @param {Node} item + * @returns {number} + */ + indexOf: function(item) { + return Array.prototype.indexOf.call(this, item); + } + }; + function LiveNodeList(node, refresh) { + this._node = node; + this._refresh = refresh; + _updateLiveList(this); + } + function _updateLiveList(list) { + var inc = list._node._inc || list._node.ownerDocument._inc; + if (list._inc !== inc) { + var ls = list._refresh(list._node); + __set__(list, "length", ls.length); + if (!list.$$length || ls.length < list.$$length) { + for (var i = ls.length; i in list; i++) { + if (Object.prototype.hasOwnProperty.call(list, i)) { + delete list[i]; + } + } + } + copy(ls, list); + list._inc = inc; + } + } + LiveNodeList.prototype.item = function(i) { + _updateLiveList(this); + return this[i] || null; + }; + _extends(LiveNodeList, NodeList); + function NamedNodeMap() { + } + function _findNodeIndex(list, node) { + var i = list.length; + while (i--) { + if (list[i] === node) { + return i; + } + } + } + function _addNamedNode(el, list, newAttr, oldAttr) { + if (oldAttr) { + list[_findNodeIndex(list, oldAttr)] = newAttr; + } else { + list[list.length++] = newAttr; + } + if (el) { + newAttr.ownerElement = el; + var doc = el.ownerDocument; + if (doc) { + oldAttr && _onRemoveAttribute(doc, el, oldAttr); + _onAddAttribute(doc, el, newAttr); + } + } + } + function _removeNamedNode(el, list, attr) { + var i = _findNodeIndex(list, attr); + if (i >= 0) { + var lastIndex = list.length - 1; + while (i < lastIndex) { + list[i] = list[++i]; + } + list.length = lastIndex; + if (el) { + var doc = el.ownerDocument; + if (doc) { + _onRemoveAttribute(doc, el, attr); + attr.ownerElement = null; + } + } + } else { + throw new DOMException(NOT_FOUND_ERR, new Error(el.tagName + "@" + attr)); + } + } + NamedNodeMap.prototype = { + length: 0, + item: NodeList.prototype.item, + getNamedItem: function(key) { + var i = this.length; + while (i--) { + var attr = this[i]; + if (attr.nodeName == key) { + return attr; + } + } + }, + setNamedItem: function(attr) { + var el = attr.ownerElement; + if (el && el != this._ownerElement) { + throw new DOMException(INUSE_ATTRIBUTE_ERR); + } + var oldAttr = this.getNamedItem(attr.nodeName); + _addNamedNode(this._ownerElement, this, attr, oldAttr); + return oldAttr; + }, + /* returns Node */ + setNamedItemNS: function(attr) { + var el = attr.ownerElement, oldAttr; + if (el && el != this._ownerElement) { + throw new DOMException(INUSE_ATTRIBUTE_ERR); + } + oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName); + _addNamedNode(this._ownerElement, this, attr, oldAttr); + return oldAttr; + }, + /* returns Node */ + removeNamedItem: function(key) { + var attr = this.getNamedItem(key); + _removeNamedNode(this._ownerElement, this, attr); + return attr; + }, + // raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR + //for level2 + removeNamedItemNS: function(namespaceURI, localName) { + var attr = this.getNamedItemNS(namespaceURI, localName); + _removeNamedNode(this._ownerElement, this, attr); + return attr; + }, + getNamedItemNS: function(namespaceURI, localName) { + var i = this.length; + while (i--) { + var node = this[i]; + if (node.localName == localName && node.namespaceURI == namespaceURI) { + return node; + } + } + return null; + } + }; + function DOMImplementation() { + } + DOMImplementation.prototype = { + /** + * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given feature is supported. + * The different implementations fairly diverged in what kind of features were reported. + * The latest version of the spec settled to force this method to always return true, where the functionality was accurate and in use. + * + * @deprecated It is deprecated and modern browsers return true in all cases. + * + * @param {string} feature + * @param {string} [version] + * @returns {boolean} always true + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN + * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core + * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard + */ + hasFeature: function(feature, version) { + return true; + }, + /** + * Creates an XML Document object of the specified type with its document element. + * + * __It behaves slightly different from the description in the living standard__: + * - There is no interface/class `XMLDocument`, it returns a `Document` instance. + * - `contentType`, `encoding`, `mode`, `origin`, `url` fields are currently not declared. + * - this implementation is not validating names or qualified names + * (when parsing XML strings, the SAX parser takes care of that) + * + * @param {string|null} namespaceURI + * @param {string} qualifiedName + * @param {DocumentType=null} doctype + * @returns {Document} + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN + * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM Level 2 Core (initial) + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core + * + * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract + * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names + * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names + */ + createDocument: function(namespaceURI, qualifiedName, doctype) { + var doc = new Document(); + doc.implementation = this; + doc.childNodes = new NodeList(); + doc.doctype = doctype || null; + if (doctype) { + doc.appendChild(doctype); + } + if (qualifiedName) { + var root = doc.createElementNS(namespaceURI, qualifiedName); + doc.appendChild(root); + } + return doc; + }, + /** + * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`. + * + * __This behavior is slightly different from the in the specs__: + * - this implementation is not validating names or qualified names + * (when parsing XML strings, the SAX parser takes care of that) + * + * @param {string} qualifiedName + * @param {string} [publicId] + * @param {string} [systemId] + * @returns {DocumentType} which can either be used with `DOMImplementation.createDocument` upon document creation + * or can be put into the document via methods like `Node.insertBefore()` or `Node.replaceChild()` + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType MDN + * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM Level 2 Core + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living Standard + * + * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract + * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names + * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names + */ + createDocumentType: function(qualifiedName, publicId, systemId) { + var node = new DocumentType(); + node.name = qualifiedName; + node.nodeName = qualifiedName; + node.publicId = publicId || ""; + node.systemId = systemId || ""; + return node; + } + }; + function Node() { + } + Node.prototype = { + firstChild: null, + lastChild: null, + previousSibling: null, + nextSibling: null, + attributes: null, + parentNode: null, + childNodes: null, + ownerDocument: null, + nodeValue: null, + namespaceURI: null, + prefix: null, + localName: null, + // Modified in DOM Level 2: + insertBefore: function(newChild, refChild) { + return _insertBefore(this, newChild, refChild); + }, + replaceChild: function(newChild, oldChild) { + _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument); + if (oldChild) { + this.removeChild(oldChild); + } + }, + removeChild: function(oldChild) { + return _removeChild(this, oldChild); + }, + appendChild: function(newChild) { + return this.insertBefore(newChild, null); + }, + hasChildNodes: function() { + return this.firstChild != null; + }, + cloneNode: function(deep) { + return cloneNode(this.ownerDocument || this, this, deep); + }, + // Modified in DOM Level 2: + normalize: function() { + var child = this.firstChild; + while (child) { + var next = child.nextSibling; + if (next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE) { + this.removeChild(next); + child.appendData(next.data); + } else { + child.normalize(); + child = next; + } + } + }, + // Introduced in DOM Level 2: + isSupported: function(feature, version) { + return this.ownerDocument.implementation.hasFeature(feature, version); + }, + // Introduced in DOM Level 2: + hasAttributes: function() { + return this.attributes.length > 0; + }, + /** + * Look up the prefix associated to the given namespace URI, starting from this node. + * **The default namespace declarations are ignored by this method.** + * See Namespace Prefix Lookup for details on the algorithm used by this method. + * + * _Note: The implementation seems to be incomplete when compared to the algorithm described in the specs._ + * + * @param {string | null} namespaceURI + * @returns {string | null} + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix + * @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo + * @see https://dom.spec.whatwg.org/#dom-node-lookupprefix + * @see https://github.com/xmldom/xmldom/issues/322 + */ + lookupPrefix: function(namespaceURI) { + var el = this; + while (el) { + var map = el._nsMap; + if (map) { + for (var n in map) { + if (Object.prototype.hasOwnProperty.call(map, n) && map[n] === namespaceURI) { + return n; + } + } + } + el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode; + } + return null; + }, + // Introduced in DOM Level 3: + lookupNamespaceURI: function(prefix) { + var el = this; + while (el) { + var map = el._nsMap; + if (map) { + if (Object.prototype.hasOwnProperty.call(map, prefix)) { + return map[prefix]; + } + } + el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode; + } + return null; + }, + // Introduced in DOM Level 3: + isDefaultNamespace: function(namespaceURI) { + var prefix = this.lookupPrefix(namespaceURI); + return prefix == null; + } + }; + function _xmlEncoder(c) { + return c == "<" && "<" || c == ">" && ">" || c == "&" && "&" || c == '"' && """ || "&#" + c.charCodeAt() + ";"; + } + copy(NodeType, Node); + copy(NodeType, Node.prototype); + function _visitNode(node, callback) { + if (callback(node)) { + return true; + } + if (node = node.firstChild) { + do { + if (_visitNode(node, callback)) { + return true; + } + } while (node = node.nextSibling); + } + } + function Document() { + this.ownerDocument = this; + } + function _onAddAttribute(doc, el, newAttr) { + doc && doc._inc++; + var ns = newAttr.namespaceURI; + if (ns === NAMESPACE.XMLNS) { + el._nsMap[newAttr.prefix ? newAttr.localName : ""] = newAttr.value; + } + } + function _onRemoveAttribute(doc, el, newAttr, remove) { + doc && doc._inc++; + var ns = newAttr.namespaceURI; + if (ns === NAMESPACE.XMLNS) { + delete el._nsMap[newAttr.prefix ? newAttr.localName : ""]; + } + } + function _onUpdateChild(doc, el, newChild) { + if (doc && doc._inc) { + doc._inc++; + var cs = el.childNodes; + if (newChild) { + cs[cs.length++] = newChild; + } else { + var child = el.firstChild; + var i = 0; + while (child) { + cs[i++] = child; + child = child.nextSibling; + } + cs.length = i; + delete cs[cs.length]; + } + } + } + function _removeChild(parentNode, child) { + var previous = child.previousSibling; + var next = child.nextSibling; + if (previous) { + previous.nextSibling = next; + } else { + parentNode.firstChild = next; + } + if (next) { + next.previousSibling = previous; + } else { + parentNode.lastChild = previous; + } + child.parentNode = null; + child.previousSibling = null; + child.nextSibling = null; + _onUpdateChild(parentNode.ownerDocument, parentNode); + return child; + } + function hasValidParentNodeType(node) { + return node && (node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE); + } + function hasInsertableNodeType(node) { + return node && (isElementNode(node) || isTextNode(node) || isDocTypeNode(node) || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.COMMENT_NODE || node.nodeType === Node.PROCESSING_INSTRUCTION_NODE); + } + function isDocTypeNode(node) { + return node && node.nodeType === Node.DOCUMENT_TYPE_NODE; + } + function isElementNode(node) { + return node && node.nodeType === Node.ELEMENT_NODE; + } + function isTextNode(node) { + return node && node.nodeType === Node.TEXT_NODE; + } + function isElementInsertionPossible(doc, child) { + var parentChildNodes = doc.childNodes || []; + if (find(parentChildNodes, isElementNode) || isDocTypeNode(child)) { + return false; + } + var docTypeNode = find(parentChildNodes, isDocTypeNode); + return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child)); + } + function isElementReplacementPossible(doc, child) { + var parentChildNodes = doc.childNodes || []; + function hasElementChildThatIsNotChild(node) { + return isElementNode(node) && node !== child; + } + if (find(parentChildNodes, hasElementChildThatIsNotChild)) { + return false; + } + var docTypeNode = find(parentChildNodes, isDocTypeNode); + return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child)); + } + function assertPreInsertionValidity1to5(parent, node, child) { + if (!hasValidParentNodeType(parent)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "Unexpected parent node type " + parent.nodeType); + } + if (child && child.parentNode !== parent) { + throw new DOMException(NOT_FOUND_ERR, "child not in parent"); + } + if ( + // 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException. + !hasInsertableNodeType(node) || // 5. If either `node` is a Text node and `parent` is a document, + // the sax parser currently adds top level text nodes, this will be fixed in 0.9.0 + // || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE) + // or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException. + isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE + ) { + throw new DOMException( + HIERARCHY_REQUEST_ERR, + "Unexpected node type " + node.nodeType + " for parent node type " + parent.nodeType + ); + } + } + function assertPreInsertionValidityInDocument(parent, node, child) { + var parentChildNodes = parent.childNodes || []; + var nodeChildNodes = node.childNodes || []; + if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + var nodeChildElements = nodeChildNodes.filter(isElementNode); + if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "More than one element or text in fragment"); + } + if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype"); + } + } + if (isElementNode(node)) { + if (!isElementInsertionPossible(parent, child)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype"); + } + } + if (isDocTypeNode(node)) { + if (find(parentChildNodes, isDocTypeNode)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one doctype is allowed"); + } + var parentElementChild = find(parentChildNodes, isElementNode); + if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element"); + } + if (!child && parentElementChild) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "Doctype can not be appended since element is present"); + } + } + } + function assertPreReplacementValidityInDocument(parent, node, child) { + var parentChildNodes = parent.childNodes || []; + var nodeChildNodes = node.childNodes || []; + if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + var nodeChildElements = nodeChildNodes.filter(isElementNode); + if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "More than one element or text in fragment"); + } + if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype"); + } + } + if (isElementNode(node)) { + if (!isElementReplacementPossible(parent, child)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype"); + } + } + if (isDocTypeNode(node)) { + let hasDoctypeChildThatIsNotChild2 = function(node2) { + return isDocTypeNode(node2) && node2 !== child; + }; + var hasDoctypeChildThatIsNotChild = hasDoctypeChildThatIsNotChild2; + if (find(parentChildNodes, hasDoctypeChildThatIsNotChild2)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one doctype is allowed"); + } + var parentElementChild = find(parentChildNodes, isElementNode); + if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { + throw new DOMException(HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element"); + } + } + } + function _insertBefore(parent, node, child, _inDocumentAssertion) { + assertPreInsertionValidity1to5(parent, node, child); + if (parent.nodeType === Node.DOCUMENT_NODE) { + (_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child); + } + var cp = node.parentNode; + if (cp) { + cp.removeChild(node); + } + if (node.nodeType === DOCUMENT_FRAGMENT_NODE) { + var newFirst = node.firstChild; + if (newFirst == null) { + return node; + } + var newLast = node.lastChild; + } else { + newFirst = newLast = node; + } + var pre = child ? child.previousSibling : parent.lastChild; + newFirst.previousSibling = pre; + newLast.nextSibling = child; + if (pre) { + pre.nextSibling = newFirst; + } else { + parent.firstChild = newFirst; + } + if (child == null) { + parent.lastChild = newLast; + } else { + child.previousSibling = newLast; + } + do { + newFirst.parentNode = parent; + } while (newFirst !== newLast && (newFirst = newFirst.nextSibling)); + _onUpdateChild(parent.ownerDocument || parent, parent); + if (node.nodeType == DOCUMENT_FRAGMENT_NODE) { + node.firstChild = node.lastChild = null; + } + return node; + } + function _appendSingleChild(parentNode, newChild) { + if (newChild.parentNode) { + newChild.parentNode.removeChild(newChild); + } + newChild.parentNode = parentNode; + newChild.previousSibling = parentNode.lastChild; + newChild.nextSibling = null; + if (newChild.previousSibling) { + newChild.previousSibling.nextSibling = newChild; + } else { + parentNode.firstChild = newChild; + } + parentNode.lastChild = newChild; + _onUpdateChild(parentNode.ownerDocument, parentNode, newChild); + return newChild; + } + Document.prototype = { + //implementation : null, + nodeName: "#document", + nodeType: DOCUMENT_NODE, + /** + * The DocumentType node of the document. + * + * @readonly + * @type DocumentType + */ + doctype: null, + documentElement: null, + _inc: 1, + insertBefore: function(newChild, refChild) { + if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) { + var child = newChild.firstChild; + while (child) { + var next = child.nextSibling; + this.insertBefore(child, refChild); + child = next; + } + return newChild; + } + _insertBefore(this, newChild, refChild); + newChild.ownerDocument = this; + if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) { + this.documentElement = newChild; + } + return newChild; + }, + removeChild: function(oldChild) { + if (this.documentElement == oldChild) { + this.documentElement = null; + } + return _removeChild(this, oldChild); + }, + replaceChild: function(newChild, oldChild) { + _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument); + newChild.ownerDocument = this; + if (oldChild) { + this.removeChild(oldChild); + } + if (isElementNode(newChild)) { + this.documentElement = newChild; + } + }, + // Introduced in DOM Level 2: + importNode: function(importedNode, deep) { + return importNode(this, importedNode, deep); + }, + // Introduced in DOM Level 2: + getElementById: function(id) { + var rtv = null; + _visitNode(this.documentElement, function(node) { + if (node.nodeType == ELEMENT_NODE) { + if (node.getAttribute("id") == id) { + rtv = node; + return true; + } + } + }); + return rtv; + }, + /** + * The `getElementsByClassName` method of `Document` interface returns an array-like object + * of all child elements which have **all** of the given class name(s). + * + * Returns an empty list if `classeNames` is an empty string or only contains HTML white space characters. + * + * + * Warning: This is a live LiveNodeList. + * Changes in the DOM will reflect in the array as the changes occur. + * If an element selected by this array no longer qualifies for the selector, + * it will automatically be removed. Be aware of this for iteration purposes. + * + * @param {string} classNames is a string representing the class name(s) to match; multiple class names are separated by (ASCII-)whitespace + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName + * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname + */ + getElementsByClassName: function(classNames) { + var classNamesSet = toOrderedSet(classNames); + return new LiveNodeList(this, function(base) { + var ls = []; + if (classNamesSet.length > 0) { + _visitNode(base.documentElement, function(node) { + if (node !== base && node.nodeType === ELEMENT_NODE) { + var nodeClassNames = node.getAttribute("class"); + if (nodeClassNames) { + var matches = classNames === nodeClassNames; + if (!matches) { + var nodeClassNamesSet = toOrderedSet(nodeClassNames); + matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet)); + } + if (matches) { + ls.push(node); + } + } + } + }); + } + return ls; + }); + }, + //document factory method: + createElement: function(tagName) { + var node = new Element(); + node.ownerDocument = this; + node.nodeName = tagName; + node.tagName = tagName; + node.localName = tagName; + node.childNodes = new NodeList(); + var attrs = node.attributes = new NamedNodeMap(); + attrs._ownerElement = node; + return node; + }, + createDocumentFragment: function() { + var node = new DocumentFragment(); + node.ownerDocument = this; + node.childNodes = new NodeList(); + return node; + }, + createTextNode: function(data) { + var node = new Text(); + node.ownerDocument = this; + node.appendData(data); + return node; + }, + createComment: function(data) { + var node = new Comment(); + node.ownerDocument = this; + node.appendData(data); + return node; + }, + createCDATASection: function(data) { + var node = new CDATASection(); + node.ownerDocument = this; + node.appendData(data); + return node; + }, + createProcessingInstruction: function(target, data) { + var node = new ProcessingInstruction(); + node.ownerDocument = this; + node.tagName = node.nodeName = node.target = target; + node.nodeValue = node.data = data; + return node; + }, + createAttribute: function(name2) { + var node = new Attr(); + node.ownerDocument = this; + node.name = name2; + node.nodeName = name2; + node.localName = name2; + node.specified = true; + return node; + }, + createEntityReference: function(name2) { + var node = new EntityReference(); + node.ownerDocument = this; + node.nodeName = name2; + return node; + }, + // Introduced in DOM Level 2: + createElementNS: function(namespaceURI, qualifiedName) { + var node = new Element(); + var pl = qualifiedName.split(":"); + var attrs = node.attributes = new NamedNodeMap(); + node.childNodes = new NodeList(); + node.ownerDocument = this; + node.nodeName = qualifiedName; + node.tagName = qualifiedName; + node.namespaceURI = namespaceURI; + if (pl.length == 2) { + node.prefix = pl[0]; + node.localName = pl[1]; + } else { + node.localName = qualifiedName; + } + attrs._ownerElement = node; + return node; + }, + // Introduced in DOM Level 2: + createAttributeNS: function(namespaceURI, qualifiedName) { + var node = new Attr(); + var pl = qualifiedName.split(":"); + node.ownerDocument = this; + node.nodeName = qualifiedName; + node.name = qualifiedName; + node.namespaceURI = namespaceURI; + node.specified = true; + if (pl.length == 2) { + node.prefix = pl[0]; + node.localName = pl[1]; + } else { + node.localName = qualifiedName; + } + return node; + } + }; + _extends(Document, Node); + function Element() { + this._nsMap = {}; + } + Element.prototype = { + nodeType: ELEMENT_NODE, + hasAttribute: function(name2) { + return this.getAttributeNode(name2) != null; + }, + getAttribute: function(name2) { + var attr = this.getAttributeNode(name2); + return attr && attr.value || ""; + }, + getAttributeNode: function(name2) { + return this.attributes.getNamedItem(name2); + }, + setAttribute: function(name2, value) { + var attr = this.ownerDocument.createAttribute(name2); + attr.value = attr.nodeValue = "" + value; + this.setAttributeNode(attr); + }, + removeAttribute: function(name2) { + var attr = this.getAttributeNode(name2); + attr && this.removeAttributeNode(attr); + }, + //four real opeartion method + appendChild: function(newChild) { + if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE) { + return this.insertBefore(newChild, null); + } else { + return _appendSingleChild(this, newChild); + } + }, + setAttributeNode: function(newAttr) { + return this.attributes.setNamedItem(newAttr); + }, + setAttributeNodeNS: function(newAttr) { + return this.attributes.setNamedItemNS(newAttr); + }, + removeAttributeNode: function(oldAttr) { + return this.attributes.removeNamedItem(oldAttr.nodeName); + }, + //get real attribute name,and remove it by removeAttributeNode + removeAttributeNS: function(namespaceURI, localName) { + var old = this.getAttributeNodeNS(namespaceURI, localName); + old && this.removeAttributeNode(old); + }, + hasAttributeNS: function(namespaceURI, localName) { + return this.getAttributeNodeNS(namespaceURI, localName) != null; + }, + getAttributeNS: function(namespaceURI, localName) { + var attr = this.getAttributeNodeNS(namespaceURI, localName); + return attr && attr.value || ""; + }, + setAttributeNS: function(namespaceURI, qualifiedName, value) { + var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName); + attr.value = attr.nodeValue = "" + value; + this.setAttributeNode(attr); + }, + getAttributeNodeNS: function(namespaceURI, localName) { + return this.attributes.getNamedItemNS(namespaceURI, localName); + }, + getElementsByTagName: function(tagName) { + return new LiveNodeList(this, function(base) { + var ls = []; + _visitNode(base, function(node) { + if (node !== base && node.nodeType == ELEMENT_NODE && (tagName === "*" || node.tagName == tagName)) { + ls.push(node); + } + }); + return ls; + }); + }, + getElementsByTagNameNS: function(namespaceURI, localName) { + return new LiveNodeList(this, function(base) { + var ls = []; + _visitNode(base, function(node) { + if (node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === "*" || node.namespaceURI === namespaceURI) && (localName === "*" || node.localName == localName)) { + ls.push(node); + } + }); + return ls; + }); + } + }; + Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName; + Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS; + _extends(Element, Node); + function Attr() { + } + Attr.prototype.nodeType = ATTRIBUTE_NODE; + _extends(Attr, Node); + function CharacterData() { + } + CharacterData.prototype = { + data: "", + substringData: function(offset, count) { + return this.data.substring(offset, offset + count); + }, + appendData: function(text) { + text = this.data + text; + this.nodeValue = this.data = text; + this.length = text.length; + }, + insertData: function(offset, text) { + this.replaceData(offset, 0, text); + }, + appendChild: function(newChild) { + throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR]); + }, + deleteData: function(offset, count) { + this.replaceData(offset, count, ""); + }, + replaceData: function(offset, count, text) { + var start = this.data.substring(0, offset); + var end = this.data.substring(offset + count); + text = start + text + end; + this.nodeValue = this.data = text; + this.length = text.length; + } + }; + _extends(CharacterData, Node); + function Text() { + } + Text.prototype = { + nodeName: "#text", + nodeType: TEXT_NODE, + splitText: function(offset) { + var text = this.data; + var newText = text.substring(offset); + text = text.substring(0, offset); + this.data = this.nodeValue = text; + this.length = text.length; + var newNode = this.ownerDocument.createTextNode(newText); + if (this.parentNode) { + this.parentNode.insertBefore(newNode, this.nextSibling); + } + return newNode; + } + }; + _extends(Text, CharacterData); + function Comment() { + } + Comment.prototype = { + nodeName: "#comment", + nodeType: COMMENT_NODE + }; + _extends(Comment, CharacterData); + function CDATASection() { + } + CDATASection.prototype = { + nodeName: "#cdata-section", + nodeType: CDATA_SECTION_NODE + }; + _extends(CDATASection, CharacterData); + function DocumentType() { + } + DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE; + _extends(DocumentType, Node); + function Notation() { + } + Notation.prototype.nodeType = NOTATION_NODE; + _extends(Notation, Node); + function Entity() { + } + Entity.prototype.nodeType = ENTITY_NODE; + _extends(Entity, Node); + function EntityReference() { + } + EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; + _extends(EntityReference, Node); + function DocumentFragment() { + } + DocumentFragment.prototype.nodeName = "#document-fragment"; + DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; + _extends(DocumentFragment, Node); + function ProcessingInstruction() { + } + ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; + _extends(ProcessingInstruction, Node); + function XMLSerializer() { + } + XMLSerializer.prototype.serializeToString = function(node, isHtml, nodeFilter) { + return nodeSerializeToString.call(node, isHtml, nodeFilter); + }; + Node.prototype.toString = nodeSerializeToString; + function nodeSerializeToString(isHtml, nodeFilter) { + var buf = []; + var refNode = this.nodeType == 9 && this.documentElement || this; + var prefix = refNode.prefix; + var uri = refNode.namespaceURI; + if (uri && prefix == null) { + var prefix = refNode.lookupPrefix(uri); + if (prefix == null) { + var visibleNamespaces = [ + { namespace: uri, prefix: null } + //{namespace:uri,prefix:''} + ]; + } + } + serializeToString(this, buf, isHtml, nodeFilter, visibleNamespaces); + return buf.join(""); + } + function needNamespaceDefine(node, isHTML, visibleNamespaces) { + var prefix = node.prefix || ""; + var uri = node.namespaceURI; + if (!uri) { + return false; + } + if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) { + return false; + } + var i = visibleNamespaces.length; + while (i--) { + var ns = visibleNamespaces[i]; + if (ns.prefix === prefix) { + return ns.namespace !== uri; + } + } + return true; + } + function addSerializedAttribute(buf, qualifiedName, value) { + buf.push(" ", qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"'); + } + function serializeToString(node, buf, isHTML, nodeFilter, visibleNamespaces) { + if (!visibleNamespaces) { + visibleNamespaces = []; + } + if (nodeFilter) { + node = nodeFilter(node); + if (node) { + if (typeof node == "string") { + buf.push(node); + return; + } + } else { + return; + } + } + switch (node.nodeType) { + case ELEMENT_NODE: + var attrs = node.attributes; + var len = attrs.length; + var child = node.firstChild; + var nodeName = node.tagName; + isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML; + var prefixedNodeName = nodeName; + if (!isHTML && !node.prefix && node.namespaceURI) { + var defaultNS; + for (var ai = 0; ai < attrs.length; ai++) { + if (attrs.item(ai).name === "xmlns") { + defaultNS = attrs.item(ai).value; + break; + } + } + if (!defaultNS) { + for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { + var namespace = visibleNamespaces[nsi]; + if (namespace.prefix === "" && namespace.namespace === node.namespaceURI) { + defaultNS = namespace.namespace; + break; + } + } + } + if (defaultNS !== node.namespaceURI) { + for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { + var namespace = visibleNamespaces[nsi]; + if (namespace.namespace === node.namespaceURI) { + if (namespace.prefix) { + prefixedNodeName = namespace.prefix + ":" + nodeName; + } + break; + } + } + } + } + buf.push("<", prefixedNodeName); + for (var i = 0; i < len; i++) { + var attr = attrs.item(i); + if (attr.prefix == "xmlns") { + visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value }); + } else if (attr.nodeName == "xmlns") { + visibleNamespaces.push({ prefix: "", namespace: attr.value }); + } + } + for (var i = 0; i < len; i++) { + var attr = attrs.item(i); + if (needNamespaceDefine(attr, isHTML, visibleNamespaces)) { + var prefix = attr.prefix || ""; + var uri = attr.namespaceURI; + addSerializedAttribute(buf, prefix ? "xmlns:" + prefix : "xmlns", uri); + visibleNamespaces.push({ prefix, namespace: uri }); + } + serializeToString(attr, buf, isHTML, nodeFilter, visibleNamespaces); + } + if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) { + var prefix = node.prefix || ""; + var uri = node.namespaceURI; + addSerializedAttribute(buf, prefix ? "xmlns:" + prefix : "xmlns", uri); + visibleNamespaces.push({ prefix, namespace: uri }); + } + if (child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)) { + buf.push(">"); + if (isHTML && /^script$/i.test(nodeName)) { + while (child) { + if (child.data) { + buf.push(child.data); + } else { + serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); + } + child = child.nextSibling; + } + } else { + while (child) { + serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); + child = child.nextSibling; + } + } + buf.push(""); + } else { + buf.push("/>"); + } + return; + case DOCUMENT_NODE: + case DOCUMENT_FRAGMENT_NODE: + var child = node.firstChild; + while (child) { + serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); + child = child.nextSibling; + } + return; + case ATTRIBUTE_NODE: + return addSerializedAttribute(buf, node.name, node.value); + case TEXT_NODE: + return buf.push( + node.data.replace(/[<&>]/g, _xmlEncoder) + ); + case CDATA_SECTION_NODE: + return buf.push(""); + case COMMENT_NODE: + return buf.push(""); + case DOCUMENT_TYPE_NODE: + var pubid = node.publicId; + var sysid = node.systemId; + buf.push(""); + } else if (sysid && sysid != ".") { + buf.push(" SYSTEM ", sysid, ">"); + } else { + var sub = node.internalSubset; + if (sub) { + buf.push(" [", sub, "]"); + } + buf.push(">"); + } + return; + case PROCESSING_INSTRUCTION_NODE: + return buf.push(""); + case ENTITY_REFERENCE_NODE: + return buf.push("&", node.nodeName, ";"); + default: + buf.push("??", node.nodeName); + } + } + function importNode(doc, node, deep) { + var node2; + switch (node.nodeType) { + case ELEMENT_NODE: + node2 = node.cloneNode(false); + node2.ownerDocument = doc; + case DOCUMENT_FRAGMENT_NODE: + break; + case ATTRIBUTE_NODE: + deep = true; + break; + } + if (!node2) { + node2 = node.cloneNode(false); + } + node2.ownerDocument = doc; + node2.parentNode = null; + if (deep) { + var child = node.firstChild; + while (child) { + node2.appendChild(importNode(doc, child, deep)); + child = child.nextSibling; + } + } + return node2; + } + function cloneNode(doc, node, deep) { + var node2 = new node.constructor(); + for (var n in node) { + if (Object.prototype.hasOwnProperty.call(node, n)) { + var v = node[n]; + if (typeof v != "object") { + if (v != node2[n]) { + node2[n] = v; + } + } + } + } + if (node.childNodes) { + node2.childNodes = new NodeList(); + } + node2.ownerDocument = doc; + switch (node2.nodeType) { + case ELEMENT_NODE: + var attrs = node.attributes; + var attrs2 = node2.attributes = new NamedNodeMap(); + var len = attrs.length; + attrs2._ownerElement = node2; + for (var i = 0; i < len; i++) { + node2.setAttributeNode(cloneNode(doc, attrs.item(i), true)); + } + break; + ; + case ATTRIBUTE_NODE: + deep = true; + } + if (deep) { + var child = node.firstChild; + while (child) { + node2.appendChild(cloneNode(doc, child, deep)); + child = child.nextSibling; + } + } + return node2; + } + function __set__(object, key, value) { + object[key] = value; + } + try { + if (Object.defineProperty) { + let getTextContent2 = function(node) { + switch (node.nodeType) { + case ELEMENT_NODE: + case DOCUMENT_FRAGMENT_NODE: + var buf = []; + node = node.firstChild; + while (node) { + if (node.nodeType !== 7 && node.nodeType !== 8) { + buf.push(getTextContent2(node)); + } + node = node.nextSibling; + } + return buf.join(""); + default: + return node.nodeValue; + } + }; + getTextContent = getTextContent2; + Object.defineProperty(LiveNodeList.prototype, "length", { + get: function() { + _updateLiveList(this); + return this.$$length; + } + }); + Object.defineProperty(Node.prototype, "textContent", { + get: function() { + return getTextContent2(this); + }, + set: function(data) { + switch (this.nodeType) { + case ELEMENT_NODE: + case DOCUMENT_FRAGMENT_NODE: + while (this.firstChild) { + this.removeChild(this.firstChild); + } + if (data || String(data)) { + this.appendChild(this.ownerDocument.createTextNode(data)); + } + break; + default: + this.data = data; + this.value = data; + this.nodeValue = data; + } + } + }); + __set__ = function(object, key, value) { + object["$$" + key] = value; + }; + } + } catch (e) { + } + var getTextContent; + exports2.DocumentType = DocumentType; + exports2.DOMException = DOMException; + exports2.DOMImplementation = DOMImplementation; + exports2.Element = Element; + exports2.Node = Node; + exports2.NodeList = NodeList; + exports2.XMLSerializer = XMLSerializer; + } +}); + +// ../../node_modules/@xmldom/xmldom/lib/entities.js +var require_entities = __commonJS({ + "../../node_modules/@xmldom/xmldom/lib/entities.js"(exports2) { + "use strict"; + var freeze = require_conventions().freeze; + exports2.XML_ENTITIES = freeze({ + amp: "&", + apos: "'", + gt: ">", + lt: "<", + quot: '"' + }); + exports2.HTML_ENTITIES = freeze({ + Aacute: "\xC1", + aacute: "\xE1", + Abreve: "\u0102", + abreve: "\u0103", + ac: "\u223E", + acd: "\u223F", + acE: "\u223E\u0333", + Acirc: "\xC2", + acirc: "\xE2", + acute: "\xB4", + Acy: "\u0410", + acy: "\u0430", + AElig: "\xC6", + aelig: "\xE6", + af: "\u2061", + Afr: "\u{1D504}", + afr: "\u{1D51E}", + Agrave: "\xC0", + agrave: "\xE0", + alefsym: "\u2135", + aleph: "\u2135", + Alpha: "\u0391", + alpha: "\u03B1", + Amacr: "\u0100", + amacr: "\u0101", + amalg: "\u2A3F", + AMP: "&", + amp: "&", + And: "\u2A53", + and: "\u2227", + andand: "\u2A55", + andd: "\u2A5C", + andslope: "\u2A58", + andv: "\u2A5A", + ang: "\u2220", + ange: "\u29A4", + angle: "\u2220", + angmsd: "\u2221", + angmsdaa: "\u29A8", + angmsdab: "\u29A9", + angmsdac: "\u29AA", + angmsdad: "\u29AB", + angmsdae: "\u29AC", + angmsdaf: "\u29AD", + angmsdag: "\u29AE", + angmsdah: "\u29AF", + angrt: "\u221F", + angrtvb: "\u22BE", + angrtvbd: "\u299D", + angsph: "\u2222", + angst: "\xC5", + angzarr: "\u237C", + Aogon: "\u0104", + aogon: "\u0105", + Aopf: "\u{1D538}", + aopf: "\u{1D552}", + ap: "\u2248", + apacir: "\u2A6F", + apE: "\u2A70", + ape: "\u224A", + apid: "\u224B", + apos: "'", + ApplyFunction: "\u2061", + approx: "\u2248", + approxeq: "\u224A", + Aring: "\xC5", + aring: "\xE5", + Ascr: "\u{1D49C}", + ascr: "\u{1D4B6}", + Assign: "\u2254", + ast: "*", + asymp: "\u2248", + asympeq: "\u224D", + Atilde: "\xC3", + atilde: "\xE3", + Auml: "\xC4", + auml: "\xE4", + awconint: "\u2233", + awint: "\u2A11", + backcong: "\u224C", + backepsilon: "\u03F6", + backprime: "\u2035", + backsim: "\u223D", + backsimeq: "\u22CD", + Backslash: "\u2216", + Barv: "\u2AE7", + barvee: "\u22BD", + Barwed: "\u2306", + barwed: "\u2305", + barwedge: "\u2305", + bbrk: "\u23B5", + bbrktbrk: "\u23B6", + bcong: "\u224C", + Bcy: "\u0411", + bcy: "\u0431", + bdquo: "\u201E", + becaus: "\u2235", + Because: "\u2235", + because: "\u2235", + bemptyv: "\u29B0", + bepsi: "\u03F6", + bernou: "\u212C", + Bernoullis: "\u212C", + Beta: "\u0392", + beta: "\u03B2", + beth: "\u2136", + between: "\u226C", + Bfr: "\u{1D505}", + bfr: "\u{1D51F}", + bigcap: "\u22C2", + bigcirc: "\u25EF", + bigcup: "\u22C3", + bigodot: "\u2A00", + bigoplus: "\u2A01", + bigotimes: "\u2A02", + bigsqcup: "\u2A06", + bigstar: "\u2605", + bigtriangledown: "\u25BD", + bigtriangleup: "\u25B3", + biguplus: "\u2A04", + bigvee: "\u22C1", + bigwedge: "\u22C0", + bkarow: "\u290D", + blacklozenge: "\u29EB", + blacksquare: "\u25AA", + blacktriangle: "\u25B4", + blacktriangledown: "\u25BE", + blacktriangleleft: "\u25C2", + blacktriangleright: "\u25B8", + blank: "\u2423", + blk12: "\u2592", + blk14: "\u2591", + blk34: "\u2593", + block: "\u2588", + bne: "=\u20E5", + bnequiv: "\u2261\u20E5", + bNot: "\u2AED", + bnot: "\u2310", + Bopf: "\u{1D539}", + bopf: "\u{1D553}", + bot: "\u22A5", + bottom: "\u22A5", + bowtie: "\u22C8", + boxbox: "\u29C9", + boxDL: "\u2557", + boxDl: "\u2556", + boxdL: "\u2555", + boxdl: "\u2510", + boxDR: "\u2554", + boxDr: "\u2553", + boxdR: "\u2552", + boxdr: "\u250C", + boxH: "\u2550", + boxh: "\u2500", + boxHD: "\u2566", + boxHd: "\u2564", + boxhD: "\u2565", + boxhd: "\u252C", + boxHU: "\u2569", + boxHu: "\u2567", + boxhU: "\u2568", + boxhu: "\u2534", + boxminus: "\u229F", + boxplus: "\u229E", + boxtimes: "\u22A0", + boxUL: "\u255D", + boxUl: "\u255C", + boxuL: "\u255B", + boxul: "\u2518", + boxUR: "\u255A", + boxUr: "\u2559", + boxuR: "\u2558", + boxur: "\u2514", + boxV: "\u2551", + boxv: "\u2502", + boxVH: "\u256C", + boxVh: "\u256B", + boxvH: "\u256A", + boxvh: "\u253C", + boxVL: "\u2563", + boxVl: "\u2562", + boxvL: "\u2561", + boxvl: "\u2524", + boxVR: "\u2560", + boxVr: "\u255F", + boxvR: "\u255E", + boxvr: "\u251C", + bprime: "\u2035", + Breve: "\u02D8", + breve: "\u02D8", + brvbar: "\xA6", + Bscr: "\u212C", + bscr: "\u{1D4B7}", + bsemi: "\u204F", + bsim: "\u223D", + bsime: "\u22CD", + bsol: "\\", + bsolb: "\u29C5", + bsolhsub: "\u27C8", + bull: "\u2022", + bullet: "\u2022", + bump: "\u224E", + bumpE: "\u2AAE", + bumpe: "\u224F", + Bumpeq: "\u224E", + bumpeq: "\u224F", + Cacute: "\u0106", + cacute: "\u0107", + Cap: "\u22D2", + cap: "\u2229", + capand: "\u2A44", + capbrcup: "\u2A49", + capcap: "\u2A4B", + capcup: "\u2A47", + capdot: "\u2A40", + CapitalDifferentialD: "\u2145", + caps: "\u2229\uFE00", + caret: "\u2041", + caron: "\u02C7", + Cayleys: "\u212D", + ccaps: "\u2A4D", + Ccaron: "\u010C", + ccaron: "\u010D", + Ccedil: "\xC7", + ccedil: "\xE7", + Ccirc: "\u0108", + ccirc: "\u0109", + Cconint: "\u2230", + ccups: "\u2A4C", + ccupssm: "\u2A50", + Cdot: "\u010A", + cdot: "\u010B", + cedil: "\xB8", + Cedilla: "\xB8", + cemptyv: "\u29B2", + cent: "\xA2", + CenterDot: "\xB7", + centerdot: "\xB7", + Cfr: "\u212D", + cfr: "\u{1D520}", + CHcy: "\u0427", + chcy: "\u0447", + check: "\u2713", + checkmark: "\u2713", + Chi: "\u03A7", + chi: "\u03C7", + cir: "\u25CB", + circ: "\u02C6", + circeq: "\u2257", + circlearrowleft: "\u21BA", + circlearrowright: "\u21BB", + circledast: "\u229B", + circledcirc: "\u229A", + circleddash: "\u229D", + CircleDot: "\u2299", + circledR: "\xAE", + circledS: "\u24C8", + CircleMinus: "\u2296", + CirclePlus: "\u2295", + CircleTimes: "\u2297", + cirE: "\u29C3", + cire: "\u2257", + cirfnint: "\u2A10", + cirmid: "\u2AEF", + cirscir: "\u29C2", + ClockwiseContourIntegral: "\u2232", + CloseCurlyDoubleQuote: "\u201D", + CloseCurlyQuote: "\u2019", + clubs: "\u2663", + clubsuit: "\u2663", + Colon: "\u2237", + colon: ":", + Colone: "\u2A74", + colone: "\u2254", + coloneq: "\u2254", + comma: ",", + commat: "@", + comp: "\u2201", + compfn: "\u2218", + complement: "\u2201", + complexes: "\u2102", + cong: "\u2245", + congdot: "\u2A6D", + Congruent: "\u2261", + Conint: "\u222F", + conint: "\u222E", + ContourIntegral: "\u222E", + Copf: "\u2102", + copf: "\u{1D554}", + coprod: "\u2210", + Coproduct: "\u2210", + COPY: "\xA9", + copy: "\xA9", + copysr: "\u2117", + CounterClockwiseContourIntegral: "\u2233", + crarr: "\u21B5", + Cross: "\u2A2F", + cross: "\u2717", + Cscr: "\u{1D49E}", + cscr: "\u{1D4B8}", + csub: "\u2ACF", + csube: "\u2AD1", + csup: "\u2AD0", + csupe: "\u2AD2", + ctdot: "\u22EF", + cudarrl: "\u2938", + cudarrr: "\u2935", + cuepr: "\u22DE", + cuesc: "\u22DF", + cularr: "\u21B6", + cularrp: "\u293D", + Cup: "\u22D3", + cup: "\u222A", + cupbrcap: "\u2A48", + CupCap: "\u224D", + cupcap: "\u2A46", + cupcup: "\u2A4A", + cupdot: "\u228D", + cupor: "\u2A45", + cups: "\u222A\uFE00", + curarr: "\u21B7", + curarrm: "\u293C", + curlyeqprec: "\u22DE", + curlyeqsucc: "\u22DF", + curlyvee: "\u22CE", + curlywedge: "\u22CF", + curren: "\xA4", + curvearrowleft: "\u21B6", + curvearrowright: "\u21B7", + cuvee: "\u22CE", + cuwed: "\u22CF", + cwconint: "\u2232", + cwint: "\u2231", + cylcty: "\u232D", + Dagger: "\u2021", + dagger: "\u2020", + daleth: "\u2138", + Darr: "\u21A1", + dArr: "\u21D3", + darr: "\u2193", + dash: "\u2010", + Dashv: "\u2AE4", + dashv: "\u22A3", + dbkarow: "\u290F", + dblac: "\u02DD", + Dcaron: "\u010E", + dcaron: "\u010F", + Dcy: "\u0414", + dcy: "\u0434", + DD: "\u2145", + dd: "\u2146", + ddagger: "\u2021", + ddarr: "\u21CA", + DDotrahd: "\u2911", + ddotseq: "\u2A77", + deg: "\xB0", + Del: "\u2207", + Delta: "\u0394", + delta: "\u03B4", + demptyv: "\u29B1", + dfisht: "\u297F", + Dfr: "\u{1D507}", + dfr: "\u{1D521}", + dHar: "\u2965", + dharl: "\u21C3", + dharr: "\u21C2", + DiacriticalAcute: "\xB4", + DiacriticalDot: "\u02D9", + DiacriticalDoubleAcute: "\u02DD", + DiacriticalGrave: "`", + DiacriticalTilde: "\u02DC", + diam: "\u22C4", + Diamond: "\u22C4", + diamond: "\u22C4", + diamondsuit: "\u2666", + diams: "\u2666", + die: "\xA8", + DifferentialD: "\u2146", + digamma: "\u03DD", + disin: "\u22F2", + div: "\xF7", + divide: "\xF7", + divideontimes: "\u22C7", + divonx: "\u22C7", + DJcy: "\u0402", + djcy: "\u0452", + dlcorn: "\u231E", + dlcrop: "\u230D", + dollar: "$", + Dopf: "\u{1D53B}", + dopf: "\u{1D555}", + Dot: "\xA8", + dot: "\u02D9", + DotDot: "\u20DC", + doteq: "\u2250", + doteqdot: "\u2251", + DotEqual: "\u2250", + dotminus: "\u2238", + dotplus: "\u2214", + dotsquare: "\u22A1", + doublebarwedge: "\u2306", + DoubleContourIntegral: "\u222F", + DoubleDot: "\xA8", + DoubleDownArrow: "\u21D3", + DoubleLeftArrow: "\u21D0", + DoubleLeftRightArrow: "\u21D4", + DoubleLeftTee: "\u2AE4", + DoubleLongLeftArrow: "\u27F8", + DoubleLongLeftRightArrow: "\u27FA", + DoubleLongRightArrow: "\u27F9", + DoubleRightArrow: "\u21D2", + DoubleRightTee: "\u22A8", + DoubleUpArrow: "\u21D1", + DoubleUpDownArrow: "\u21D5", + DoubleVerticalBar: "\u2225", + DownArrow: "\u2193", + Downarrow: "\u21D3", + downarrow: "\u2193", + DownArrowBar: "\u2913", + DownArrowUpArrow: "\u21F5", + DownBreve: "\u0311", + downdownarrows: "\u21CA", + downharpoonleft: "\u21C3", + downharpoonright: "\u21C2", + DownLeftRightVector: "\u2950", + DownLeftTeeVector: "\u295E", + DownLeftVector: "\u21BD", + DownLeftVectorBar: "\u2956", + DownRightTeeVector: "\u295F", + DownRightVector: "\u21C1", + DownRightVectorBar: "\u2957", + DownTee: "\u22A4", + DownTeeArrow: "\u21A7", + drbkarow: "\u2910", + drcorn: "\u231F", + drcrop: "\u230C", + Dscr: "\u{1D49F}", + dscr: "\u{1D4B9}", + DScy: "\u0405", + dscy: "\u0455", + dsol: "\u29F6", + Dstrok: "\u0110", + dstrok: "\u0111", + dtdot: "\u22F1", + dtri: "\u25BF", + dtrif: "\u25BE", + duarr: "\u21F5", + duhar: "\u296F", + dwangle: "\u29A6", + DZcy: "\u040F", + dzcy: "\u045F", + dzigrarr: "\u27FF", + Eacute: "\xC9", + eacute: "\xE9", + easter: "\u2A6E", + Ecaron: "\u011A", + ecaron: "\u011B", + ecir: "\u2256", + Ecirc: "\xCA", + ecirc: "\xEA", + ecolon: "\u2255", + Ecy: "\u042D", + ecy: "\u044D", + eDDot: "\u2A77", + Edot: "\u0116", + eDot: "\u2251", + edot: "\u0117", + ee: "\u2147", + efDot: "\u2252", + Efr: "\u{1D508}", + efr: "\u{1D522}", + eg: "\u2A9A", + Egrave: "\xC8", + egrave: "\xE8", + egs: "\u2A96", + egsdot: "\u2A98", + el: "\u2A99", + Element: "\u2208", + elinters: "\u23E7", + ell: "\u2113", + els: "\u2A95", + elsdot: "\u2A97", + Emacr: "\u0112", + emacr: "\u0113", + empty: "\u2205", + emptyset: "\u2205", + EmptySmallSquare: "\u25FB", + emptyv: "\u2205", + EmptyVerySmallSquare: "\u25AB", + emsp: "\u2003", + emsp13: "\u2004", + emsp14: "\u2005", + ENG: "\u014A", + eng: "\u014B", + ensp: "\u2002", + Eogon: "\u0118", + eogon: "\u0119", + Eopf: "\u{1D53C}", + eopf: "\u{1D556}", + epar: "\u22D5", + eparsl: "\u29E3", + eplus: "\u2A71", + epsi: "\u03B5", + Epsilon: "\u0395", + epsilon: "\u03B5", + epsiv: "\u03F5", + eqcirc: "\u2256", + eqcolon: "\u2255", + eqsim: "\u2242", + eqslantgtr: "\u2A96", + eqslantless: "\u2A95", + Equal: "\u2A75", + equals: "=", + EqualTilde: "\u2242", + equest: "\u225F", + Equilibrium: "\u21CC", + equiv: "\u2261", + equivDD: "\u2A78", + eqvparsl: "\u29E5", + erarr: "\u2971", + erDot: "\u2253", + Escr: "\u2130", + escr: "\u212F", + esdot: "\u2250", + Esim: "\u2A73", + esim: "\u2242", + Eta: "\u0397", + eta: "\u03B7", + ETH: "\xD0", + eth: "\xF0", + Euml: "\xCB", + euml: "\xEB", + euro: "\u20AC", + excl: "!", + exist: "\u2203", + Exists: "\u2203", + expectation: "\u2130", + ExponentialE: "\u2147", + exponentiale: "\u2147", + fallingdotseq: "\u2252", + Fcy: "\u0424", + fcy: "\u0444", + female: "\u2640", + ffilig: "\uFB03", + fflig: "\uFB00", + ffllig: "\uFB04", + Ffr: "\u{1D509}", + ffr: "\u{1D523}", + filig: "\uFB01", + FilledSmallSquare: "\u25FC", + FilledVerySmallSquare: "\u25AA", + fjlig: "fj", + flat: "\u266D", + fllig: "\uFB02", + fltns: "\u25B1", + fnof: "\u0192", + Fopf: "\u{1D53D}", + fopf: "\u{1D557}", + ForAll: "\u2200", + forall: "\u2200", + fork: "\u22D4", + forkv: "\u2AD9", + Fouriertrf: "\u2131", + fpartint: "\u2A0D", + frac12: "\xBD", + frac13: "\u2153", + frac14: "\xBC", + frac15: "\u2155", + frac16: "\u2159", + frac18: "\u215B", + frac23: "\u2154", + frac25: "\u2156", + frac34: "\xBE", + frac35: "\u2157", + frac38: "\u215C", + frac45: "\u2158", + frac56: "\u215A", + frac58: "\u215D", + frac78: "\u215E", + frasl: "\u2044", + frown: "\u2322", + Fscr: "\u2131", + fscr: "\u{1D4BB}", + gacute: "\u01F5", + Gamma: "\u0393", + gamma: "\u03B3", + Gammad: "\u03DC", + gammad: "\u03DD", + gap: "\u2A86", + Gbreve: "\u011E", + gbreve: "\u011F", + Gcedil: "\u0122", + Gcirc: "\u011C", + gcirc: "\u011D", + Gcy: "\u0413", + gcy: "\u0433", + Gdot: "\u0120", + gdot: "\u0121", + gE: "\u2267", + ge: "\u2265", + gEl: "\u2A8C", + gel: "\u22DB", + geq: "\u2265", + geqq: "\u2267", + geqslant: "\u2A7E", + ges: "\u2A7E", + gescc: "\u2AA9", + gesdot: "\u2A80", + gesdoto: "\u2A82", + gesdotol: "\u2A84", + gesl: "\u22DB\uFE00", + gesles: "\u2A94", + Gfr: "\u{1D50A}", + gfr: "\u{1D524}", + Gg: "\u22D9", + gg: "\u226B", + ggg: "\u22D9", + gimel: "\u2137", + GJcy: "\u0403", + gjcy: "\u0453", + gl: "\u2277", + gla: "\u2AA5", + glE: "\u2A92", + glj: "\u2AA4", + gnap: "\u2A8A", + gnapprox: "\u2A8A", + gnE: "\u2269", + gne: "\u2A88", + gneq: "\u2A88", + gneqq: "\u2269", + gnsim: "\u22E7", + Gopf: "\u{1D53E}", + gopf: "\u{1D558}", + grave: "`", + GreaterEqual: "\u2265", + GreaterEqualLess: "\u22DB", + GreaterFullEqual: "\u2267", + GreaterGreater: "\u2AA2", + GreaterLess: "\u2277", + GreaterSlantEqual: "\u2A7E", + GreaterTilde: "\u2273", + Gscr: "\u{1D4A2}", + gscr: "\u210A", + gsim: "\u2273", + gsime: "\u2A8E", + gsiml: "\u2A90", + Gt: "\u226B", + GT: ">", + gt: ">", + gtcc: "\u2AA7", + gtcir: "\u2A7A", + gtdot: "\u22D7", + gtlPar: "\u2995", + gtquest: "\u2A7C", + gtrapprox: "\u2A86", + gtrarr: "\u2978", + gtrdot: "\u22D7", + gtreqless: "\u22DB", + gtreqqless: "\u2A8C", + gtrless: "\u2277", + gtrsim: "\u2273", + gvertneqq: "\u2269\uFE00", + gvnE: "\u2269\uFE00", + Hacek: "\u02C7", + hairsp: "\u200A", + half: "\xBD", + hamilt: "\u210B", + HARDcy: "\u042A", + hardcy: "\u044A", + hArr: "\u21D4", + harr: "\u2194", + harrcir: "\u2948", + harrw: "\u21AD", + Hat: "^", + hbar: "\u210F", + Hcirc: "\u0124", + hcirc: "\u0125", + hearts: "\u2665", + heartsuit: "\u2665", + hellip: "\u2026", + hercon: "\u22B9", + Hfr: "\u210C", + hfr: "\u{1D525}", + HilbertSpace: "\u210B", + hksearow: "\u2925", + hkswarow: "\u2926", + hoarr: "\u21FF", + homtht: "\u223B", + hookleftarrow: "\u21A9", + hookrightarrow: "\u21AA", + Hopf: "\u210D", + hopf: "\u{1D559}", + horbar: "\u2015", + HorizontalLine: "\u2500", + Hscr: "\u210B", + hscr: "\u{1D4BD}", + hslash: "\u210F", + Hstrok: "\u0126", + hstrok: "\u0127", + HumpDownHump: "\u224E", + HumpEqual: "\u224F", + hybull: "\u2043", + hyphen: "\u2010", + Iacute: "\xCD", + iacute: "\xED", + ic: "\u2063", + Icirc: "\xCE", + icirc: "\xEE", + Icy: "\u0418", + icy: "\u0438", + Idot: "\u0130", + IEcy: "\u0415", + iecy: "\u0435", + iexcl: "\xA1", + iff: "\u21D4", + Ifr: "\u2111", + ifr: "\u{1D526}", + Igrave: "\xCC", + igrave: "\xEC", + ii: "\u2148", + iiiint: "\u2A0C", + iiint: "\u222D", + iinfin: "\u29DC", + iiota: "\u2129", + IJlig: "\u0132", + ijlig: "\u0133", + Im: "\u2111", + Imacr: "\u012A", + imacr: "\u012B", + image: "\u2111", + ImaginaryI: "\u2148", + imagline: "\u2110", + imagpart: "\u2111", + imath: "\u0131", + imof: "\u22B7", + imped: "\u01B5", + Implies: "\u21D2", + in: "\u2208", + incare: "\u2105", + infin: "\u221E", + infintie: "\u29DD", + inodot: "\u0131", + Int: "\u222C", + int: "\u222B", + intcal: "\u22BA", + integers: "\u2124", + Integral: "\u222B", + intercal: "\u22BA", + Intersection: "\u22C2", + intlarhk: "\u2A17", + intprod: "\u2A3C", + InvisibleComma: "\u2063", + InvisibleTimes: "\u2062", + IOcy: "\u0401", + iocy: "\u0451", + Iogon: "\u012E", + iogon: "\u012F", + Iopf: "\u{1D540}", + iopf: "\u{1D55A}", + Iota: "\u0399", + iota: "\u03B9", + iprod: "\u2A3C", + iquest: "\xBF", + Iscr: "\u2110", + iscr: "\u{1D4BE}", + isin: "\u2208", + isindot: "\u22F5", + isinE: "\u22F9", + isins: "\u22F4", + isinsv: "\u22F3", + isinv: "\u2208", + it: "\u2062", + Itilde: "\u0128", + itilde: "\u0129", + Iukcy: "\u0406", + iukcy: "\u0456", + Iuml: "\xCF", + iuml: "\xEF", + Jcirc: "\u0134", + jcirc: "\u0135", + Jcy: "\u0419", + jcy: "\u0439", + Jfr: "\u{1D50D}", + jfr: "\u{1D527}", + jmath: "\u0237", + Jopf: "\u{1D541}", + jopf: "\u{1D55B}", + Jscr: "\u{1D4A5}", + jscr: "\u{1D4BF}", + Jsercy: "\u0408", + jsercy: "\u0458", + Jukcy: "\u0404", + jukcy: "\u0454", + Kappa: "\u039A", + kappa: "\u03BA", + kappav: "\u03F0", + Kcedil: "\u0136", + kcedil: "\u0137", + Kcy: "\u041A", + kcy: "\u043A", + Kfr: "\u{1D50E}", + kfr: "\u{1D528}", + kgreen: "\u0138", + KHcy: "\u0425", + khcy: "\u0445", + KJcy: "\u040C", + kjcy: "\u045C", + Kopf: "\u{1D542}", + kopf: "\u{1D55C}", + Kscr: "\u{1D4A6}", + kscr: "\u{1D4C0}", + lAarr: "\u21DA", + Lacute: "\u0139", + lacute: "\u013A", + laemptyv: "\u29B4", + lagran: "\u2112", + Lambda: "\u039B", + lambda: "\u03BB", + Lang: "\u27EA", + lang: "\u27E8", + langd: "\u2991", + langle: "\u27E8", + lap: "\u2A85", + Laplacetrf: "\u2112", + laquo: "\xAB", + Larr: "\u219E", + lArr: "\u21D0", + larr: "\u2190", + larrb: "\u21E4", + larrbfs: "\u291F", + larrfs: "\u291D", + larrhk: "\u21A9", + larrlp: "\u21AB", + larrpl: "\u2939", + larrsim: "\u2973", + larrtl: "\u21A2", + lat: "\u2AAB", + lAtail: "\u291B", + latail: "\u2919", + late: "\u2AAD", + lates: "\u2AAD\uFE00", + lBarr: "\u290E", + lbarr: "\u290C", + lbbrk: "\u2772", + lbrace: "{", + lbrack: "[", + lbrke: "\u298B", + lbrksld: "\u298F", + lbrkslu: "\u298D", + Lcaron: "\u013D", + lcaron: "\u013E", + Lcedil: "\u013B", + lcedil: "\u013C", + lceil: "\u2308", + lcub: "{", + Lcy: "\u041B", + lcy: "\u043B", + ldca: "\u2936", + ldquo: "\u201C", + ldquor: "\u201E", + ldrdhar: "\u2967", + ldrushar: "\u294B", + ldsh: "\u21B2", + lE: "\u2266", + le: "\u2264", + LeftAngleBracket: "\u27E8", + LeftArrow: "\u2190", + Leftarrow: "\u21D0", + leftarrow: "\u2190", + LeftArrowBar: "\u21E4", + LeftArrowRightArrow: "\u21C6", + leftarrowtail: "\u21A2", + LeftCeiling: "\u2308", + LeftDoubleBracket: "\u27E6", + LeftDownTeeVector: "\u2961", + LeftDownVector: "\u21C3", + LeftDownVectorBar: "\u2959", + LeftFloor: "\u230A", + leftharpoondown: "\u21BD", + leftharpoonup: "\u21BC", + leftleftarrows: "\u21C7", + LeftRightArrow: "\u2194", + Leftrightarrow: "\u21D4", + leftrightarrow: "\u2194", + leftrightarrows: "\u21C6", + leftrightharpoons: "\u21CB", + leftrightsquigarrow: "\u21AD", + LeftRightVector: "\u294E", + LeftTee: "\u22A3", + LeftTeeArrow: "\u21A4", + LeftTeeVector: "\u295A", + leftthreetimes: "\u22CB", + LeftTriangle: "\u22B2", + LeftTriangleBar: "\u29CF", + LeftTriangleEqual: "\u22B4", + LeftUpDownVector: "\u2951", + LeftUpTeeVector: "\u2960", + LeftUpVector: "\u21BF", + LeftUpVectorBar: "\u2958", + LeftVector: "\u21BC", + LeftVectorBar: "\u2952", + lEg: "\u2A8B", + leg: "\u22DA", + leq: "\u2264", + leqq: "\u2266", + leqslant: "\u2A7D", + les: "\u2A7D", + lescc: "\u2AA8", + lesdot: "\u2A7F", + lesdoto: "\u2A81", + lesdotor: "\u2A83", + lesg: "\u22DA\uFE00", + lesges: "\u2A93", + lessapprox: "\u2A85", + lessdot: "\u22D6", + lesseqgtr: "\u22DA", + lesseqqgtr: "\u2A8B", + LessEqualGreater: "\u22DA", + LessFullEqual: "\u2266", + LessGreater: "\u2276", + lessgtr: "\u2276", + LessLess: "\u2AA1", + lesssim: "\u2272", + LessSlantEqual: "\u2A7D", + LessTilde: "\u2272", + lfisht: "\u297C", + lfloor: "\u230A", + Lfr: "\u{1D50F}", + lfr: "\u{1D529}", + lg: "\u2276", + lgE: "\u2A91", + lHar: "\u2962", + lhard: "\u21BD", + lharu: "\u21BC", + lharul: "\u296A", + lhblk: "\u2584", + LJcy: "\u0409", + ljcy: "\u0459", + Ll: "\u22D8", + ll: "\u226A", + llarr: "\u21C7", + llcorner: "\u231E", + Lleftarrow: "\u21DA", + llhard: "\u296B", + lltri: "\u25FA", + Lmidot: "\u013F", + lmidot: "\u0140", + lmoust: "\u23B0", + lmoustache: "\u23B0", + lnap: "\u2A89", + lnapprox: "\u2A89", + lnE: "\u2268", + lne: "\u2A87", + lneq: "\u2A87", + lneqq: "\u2268", + lnsim: "\u22E6", + loang: "\u27EC", + loarr: "\u21FD", + lobrk: "\u27E6", + LongLeftArrow: "\u27F5", + Longleftarrow: "\u27F8", + longleftarrow: "\u27F5", + LongLeftRightArrow: "\u27F7", + Longleftrightarrow: "\u27FA", + longleftrightarrow: "\u27F7", + longmapsto: "\u27FC", + LongRightArrow: "\u27F6", + Longrightarrow: "\u27F9", + longrightarrow: "\u27F6", + looparrowleft: "\u21AB", + looparrowright: "\u21AC", + lopar: "\u2985", + Lopf: "\u{1D543}", + lopf: "\u{1D55D}", + loplus: "\u2A2D", + lotimes: "\u2A34", + lowast: "\u2217", + lowbar: "_", + LowerLeftArrow: "\u2199", + LowerRightArrow: "\u2198", + loz: "\u25CA", + lozenge: "\u25CA", + lozf: "\u29EB", + lpar: "(", + lparlt: "\u2993", + lrarr: "\u21C6", + lrcorner: "\u231F", + lrhar: "\u21CB", + lrhard: "\u296D", + lrm: "\u200E", + lrtri: "\u22BF", + lsaquo: "\u2039", + Lscr: "\u2112", + lscr: "\u{1D4C1}", + Lsh: "\u21B0", + lsh: "\u21B0", + lsim: "\u2272", + lsime: "\u2A8D", + lsimg: "\u2A8F", + lsqb: "[", + lsquo: "\u2018", + lsquor: "\u201A", + Lstrok: "\u0141", + lstrok: "\u0142", + Lt: "\u226A", + LT: "<", + lt: "<", + ltcc: "\u2AA6", + ltcir: "\u2A79", + ltdot: "\u22D6", + lthree: "\u22CB", + ltimes: "\u22C9", + ltlarr: "\u2976", + ltquest: "\u2A7B", + ltri: "\u25C3", + ltrie: "\u22B4", + ltrif: "\u25C2", + ltrPar: "\u2996", + lurdshar: "\u294A", + luruhar: "\u2966", + lvertneqq: "\u2268\uFE00", + lvnE: "\u2268\uFE00", + macr: "\xAF", + male: "\u2642", + malt: "\u2720", + maltese: "\u2720", + Map: "\u2905", + map: "\u21A6", + mapsto: "\u21A6", + mapstodown: "\u21A7", + mapstoleft: "\u21A4", + mapstoup: "\u21A5", + marker: "\u25AE", + mcomma: "\u2A29", + Mcy: "\u041C", + mcy: "\u043C", + mdash: "\u2014", + mDDot: "\u223A", + measuredangle: "\u2221", + MediumSpace: "\u205F", + Mellintrf: "\u2133", + Mfr: "\u{1D510}", + mfr: "\u{1D52A}", + mho: "\u2127", + micro: "\xB5", + mid: "\u2223", + midast: "*", + midcir: "\u2AF0", + middot: "\xB7", + minus: "\u2212", + minusb: "\u229F", + minusd: "\u2238", + minusdu: "\u2A2A", + MinusPlus: "\u2213", + mlcp: "\u2ADB", + mldr: "\u2026", + mnplus: "\u2213", + models: "\u22A7", + Mopf: "\u{1D544}", + mopf: "\u{1D55E}", + mp: "\u2213", + Mscr: "\u2133", + mscr: "\u{1D4C2}", + mstpos: "\u223E", + Mu: "\u039C", + mu: "\u03BC", + multimap: "\u22B8", + mumap: "\u22B8", + nabla: "\u2207", + Nacute: "\u0143", + nacute: "\u0144", + nang: "\u2220\u20D2", + nap: "\u2249", + napE: "\u2A70\u0338", + napid: "\u224B\u0338", + napos: "\u0149", + napprox: "\u2249", + natur: "\u266E", + natural: "\u266E", + naturals: "\u2115", + nbsp: "\xA0", + nbump: "\u224E\u0338", + nbumpe: "\u224F\u0338", + ncap: "\u2A43", + Ncaron: "\u0147", + ncaron: "\u0148", + Ncedil: "\u0145", + ncedil: "\u0146", + ncong: "\u2247", + ncongdot: "\u2A6D\u0338", + ncup: "\u2A42", + Ncy: "\u041D", + ncy: "\u043D", + ndash: "\u2013", + ne: "\u2260", + nearhk: "\u2924", + neArr: "\u21D7", + nearr: "\u2197", + nearrow: "\u2197", + nedot: "\u2250\u0338", + NegativeMediumSpace: "\u200B", + NegativeThickSpace: "\u200B", + NegativeThinSpace: "\u200B", + NegativeVeryThinSpace: "\u200B", + nequiv: "\u2262", + nesear: "\u2928", + nesim: "\u2242\u0338", + NestedGreaterGreater: "\u226B", + NestedLessLess: "\u226A", + NewLine: "\n", + nexist: "\u2204", + nexists: "\u2204", + Nfr: "\u{1D511}", + nfr: "\u{1D52B}", + ngE: "\u2267\u0338", + nge: "\u2271", + ngeq: "\u2271", + ngeqq: "\u2267\u0338", + ngeqslant: "\u2A7E\u0338", + nges: "\u2A7E\u0338", + nGg: "\u22D9\u0338", + ngsim: "\u2275", + nGt: "\u226B\u20D2", + ngt: "\u226F", + ngtr: "\u226F", + nGtv: "\u226B\u0338", + nhArr: "\u21CE", + nharr: "\u21AE", + nhpar: "\u2AF2", + ni: "\u220B", + nis: "\u22FC", + nisd: "\u22FA", + niv: "\u220B", + NJcy: "\u040A", + njcy: "\u045A", + nlArr: "\u21CD", + nlarr: "\u219A", + nldr: "\u2025", + nlE: "\u2266\u0338", + nle: "\u2270", + nLeftarrow: "\u21CD", + nleftarrow: "\u219A", + nLeftrightarrow: "\u21CE", + nleftrightarrow: "\u21AE", + nleq: "\u2270", + nleqq: "\u2266\u0338", + nleqslant: "\u2A7D\u0338", + nles: "\u2A7D\u0338", + nless: "\u226E", + nLl: "\u22D8\u0338", + nlsim: "\u2274", + nLt: "\u226A\u20D2", + nlt: "\u226E", + nltri: "\u22EA", + nltrie: "\u22EC", + nLtv: "\u226A\u0338", + nmid: "\u2224", + NoBreak: "\u2060", + NonBreakingSpace: "\xA0", + Nopf: "\u2115", + nopf: "\u{1D55F}", + Not: "\u2AEC", + not: "\xAC", + NotCongruent: "\u2262", + NotCupCap: "\u226D", + NotDoubleVerticalBar: "\u2226", + NotElement: "\u2209", + NotEqual: "\u2260", + NotEqualTilde: "\u2242\u0338", + NotExists: "\u2204", + NotGreater: "\u226F", + NotGreaterEqual: "\u2271", + NotGreaterFullEqual: "\u2267\u0338", + NotGreaterGreater: "\u226B\u0338", + NotGreaterLess: "\u2279", + NotGreaterSlantEqual: "\u2A7E\u0338", + NotGreaterTilde: "\u2275", + NotHumpDownHump: "\u224E\u0338", + NotHumpEqual: "\u224F\u0338", + notin: "\u2209", + notindot: "\u22F5\u0338", + notinE: "\u22F9\u0338", + notinva: "\u2209", + notinvb: "\u22F7", + notinvc: "\u22F6", + NotLeftTriangle: "\u22EA", + NotLeftTriangleBar: "\u29CF\u0338", + NotLeftTriangleEqual: "\u22EC", + NotLess: "\u226E", + NotLessEqual: "\u2270", + NotLessGreater: "\u2278", + NotLessLess: "\u226A\u0338", + NotLessSlantEqual: "\u2A7D\u0338", + NotLessTilde: "\u2274", + NotNestedGreaterGreater: "\u2AA2\u0338", + NotNestedLessLess: "\u2AA1\u0338", + notni: "\u220C", + notniva: "\u220C", + notnivb: "\u22FE", + notnivc: "\u22FD", + NotPrecedes: "\u2280", + NotPrecedesEqual: "\u2AAF\u0338", + NotPrecedesSlantEqual: "\u22E0", + NotReverseElement: "\u220C", + NotRightTriangle: "\u22EB", + NotRightTriangleBar: "\u29D0\u0338", + NotRightTriangleEqual: "\u22ED", + NotSquareSubset: "\u228F\u0338", + NotSquareSubsetEqual: "\u22E2", + NotSquareSuperset: "\u2290\u0338", + NotSquareSupersetEqual: "\u22E3", + NotSubset: "\u2282\u20D2", + NotSubsetEqual: "\u2288", + NotSucceeds: "\u2281", + NotSucceedsEqual: "\u2AB0\u0338", + NotSucceedsSlantEqual: "\u22E1", + NotSucceedsTilde: "\u227F\u0338", + NotSuperset: "\u2283\u20D2", + NotSupersetEqual: "\u2289", + NotTilde: "\u2241", + NotTildeEqual: "\u2244", + NotTildeFullEqual: "\u2247", + NotTildeTilde: "\u2249", + NotVerticalBar: "\u2224", + npar: "\u2226", + nparallel: "\u2226", + nparsl: "\u2AFD\u20E5", + npart: "\u2202\u0338", + npolint: "\u2A14", + npr: "\u2280", + nprcue: "\u22E0", + npre: "\u2AAF\u0338", + nprec: "\u2280", + npreceq: "\u2AAF\u0338", + nrArr: "\u21CF", + nrarr: "\u219B", + nrarrc: "\u2933\u0338", + nrarrw: "\u219D\u0338", + nRightarrow: "\u21CF", + nrightarrow: "\u219B", + nrtri: "\u22EB", + nrtrie: "\u22ED", + nsc: "\u2281", + nsccue: "\u22E1", + nsce: "\u2AB0\u0338", + Nscr: "\u{1D4A9}", + nscr: "\u{1D4C3}", + nshortmid: "\u2224", + nshortparallel: "\u2226", + nsim: "\u2241", + nsime: "\u2244", + nsimeq: "\u2244", + nsmid: "\u2224", + nspar: "\u2226", + nsqsube: "\u22E2", + nsqsupe: "\u22E3", + nsub: "\u2284", + nsubE: "\u2AC5\u0338", + nsube: "\u2288", + nsubset: "\u2282\u20D2", + nsubseteq: "\u2288", + nsubseteqq: "\u2AC5\u0338", + nsucc: "\u2281", + nsucceq: "\u2AB0\u0338", + nsup: "\u2285", + nsupE: "\u2AC6\u0338", + nsupe: "\u2289", + nsupset: "\u2283\u20D2", + nsupseteq: "\u2289", + nsupseteqq: "\u2AC6\u0338", + ntgl: "\u2279", + Ntilde: "\xD1", + ntilde: "\xF1", + ntlg: "\u2278", + ntriangleleft: "\u22EA", + ntrianglelefteq: "\u22EC", + ntriangleright: "\u22EB", + ntrianglerighteq: "\u22ED", + Nu: "\u039D", + nu: "\u03BD", + num: "#", + numero: "\u2116", + numsp: "\u2007", + nvap: "\u224D\u20D2", + nVDash: "\u22AF", + nVdash: "\u22AE", + nvDash: "\u22AD", + nvdash: "\u22AC", + nvge: "\u2265\u20D2", + nvgt: ">\u20D2", + nvHarr: "\u2904", + nvinfin: "\u29DE", + nvlArr: "\u2902", + nvle: "\u2264\u20D2", + nvlt: "<\u20D2", + nvltrie: "\u22B4\u20D2", + nvrArr: "\u2903", + nvrtrie: "\u22B5\u20D2", + nvsim: "\u223C\u20D2", + nwarhk: "\u2923", + nwArr: "\u21D6", + nwarr: "\u2196", + nwarrow: "\u2196", + nwnear: "\u2927", + Oacute: "\xD3", + oacute: "\xF3", + oast: "\u229B", + ocir: "\u229A", + Ocirc: "\xD4", + ocirc: "\xF4", + Ocy: "\u041E", + ocy: "\u043E", + odash: "\u229D", + Odblac: "\u0150", + odblac: "\u0151", + odiv: "\u2A38", + odot: "\u2299", + odsold: "\u29BC", + OElig: "\u0152", + oelig: "\u0153", + ofcir: "\u29BF", + Ofr: "\u{1D512}", + ofr: "\u{1D52C}", + ogon: "\u02DB", + Ograve: "\xD2", + ograve: "\xF2", + ogt: "\u29C1", + ohbar: "\u29B5", + ohm: "\u03A9", + oint: "\u222E", + olarr: "\u21BA", + olcir: "\u29BE", + olcross: "\u29BB", + oline: "\u203E", + olt: "\u29C0", + Omacr: "\u014C", + omacr: "\u014D", + Omega: "\u03A9", + omega: "\u03C9", + Omicron: "\u039F", + omicron: "\u03BF", + omid: "\u29B6", + ominus: "\u2296", + Oopf: "\u{1D546}", + oopf: "\u{1D560}", + opar: "\u29B7", + OpenCurlyDoubleQuote: "\u201C", + OpenCurlyQuote: "\u2018", + operp: "\u29B9", + oplus: "\u2295", + Or: "\u2A54", + or: "\u2228", + orarr: "\u21BB", + ord: "\u2A5D", + order: "\u2134", + orderof: "\u2134", + ordf: "\xAA", + ordm: "\xBA", + origof: "\u22B6", + oror: "\u2A56", + orslope: "\u2A57", + orv: "\u2A5B", + oS: "\u24C8", + Oscr: "\u{1D4AA}", + oscr: "\u2134", + Oslash: "\xD8", + oslash: "\xF8", + osol: "\u2298", + Otilde: "\xD5", + otilde: "\xF5", + Otimes: "\u2A37", + otimes: "\u2297", + otimesas: "\u2A36", + Ouml: "\xD6", + ouml: "\xF6", + ovbar: "\u233D", + OverBar: "\u203E", + OverBrace: "\u23DE", + OverBracket: "\u23B4", + OverParenthesis: "\u23DC", + par: "\u2225", + para: "\xB6", + parallel: "\u2225", + parsim: "\u2AF3", + parsl: "\u2AFD", + part: "\u2202", + PartialD: "\u2202", + Pcy: "\u041F", + pcy: "\u043F", + percnt: "%", + period: ".", + permil: "\u2030", + perp: "\u22A5", + pertenk: "\u2031", + Pfr: "\u{1D513}", + pfr: "\u{1D52D}", + Phi: "\u03A6", + phi: "\u03C6", + phiv: "\u03D5", + phmmat: "\u2133", + phone: "\u260E", + Pi: "\u03A0", + pi: "\u03C0", + pitchfork: "\u22D4", + piv: "\u03D6", + planck: "\u210F", + planckh: "\u210E", + plankv: "\u210F", + plus: "+", + plusacir: "\u2A23", + plusb: "\u229E", + pluscir: "\u2A22", + plusdo: "\u2214", + plusdu: "\u2A25", + pluse: "\u2A72", + PlusMinus: "\xB1", + plusmn: "\xB1", + plussim: "\u2A26", + plustwo: "\u2A27", + pm: "\xB1", + Poincareplane: "\u210C", + pointint: "\u2A15", + Popf: "\u2119", + popf: "\u{1D561}", + pound: "\xA3", + Pr: "\u2ABB", + pr: "\u227A", + prap: "\u2AB7", + prcue: "\u227C", + prE: "\u2AB3", + pre: "\u2AAF", + prec: "\u227A", + precapprox: "\u2AB7", + preccurlyeq: "\u227C", + Precedes: "\u227A", + PrecedesEqual: "\u2AAF", + PrecedesSlantEqual: "\u227C", + PrecedesTilde: "\u227E", + preceq: "\u2AAF", + precnapprox: "\u2AB9", + precneqq: "\u2AB5", + precnsim: "\u22E8", + precsim: "\u227E", + Prime: "\u2033", + prime: "\u2032", + primes: "\u2119", + prnap: "\u2AB9", + prnE: "\u2AB5", + prnsim: "\u22E8", + prod: "\u220F", + Product: "\u220F", + profalar: "\u232E", + profline: "\u2312", + profsurf: "\u2313", + prop: "\u221D", + Proportion: "\u2237", + Proportional: "\u221D", + propto: "\u221D", + prsim: "\u227E", + prurel: "\u22B0", + Pscr: "\u{1D4AB}", + pscr: "\u{1D4C5}", + Psi: "\u03A8", + psi: "\u03C8", + puncsp: "\u2008", + Qfr: "\u{1D514}", + qfr: "\u{1D52E}", + qint: "\u2A0C", + Qopf: "\u211A", + qopf: "\u{1D562}", + qprime: "\u2057", + Qscr: "\u{1D4AC}", + qscr: "\u{1D4C6}", + quaternions: "\u210D", + quatint: "\u2A16", + quest: "?", + questeq: "\u225F", + QUOT: '"', + quot: '"', + rAarr: "\u21DB", + race: "\u223D\u0331", + Racute: "\u0154", + racute: "\u0155", + radic: "\u221A", + raemptyv: "\u29B3", + Rang: "\u27EB", + rang: "\u27E9", + rangd: "\u2992", + range: "\u29A5", + rangle: "\u27E9", + raquo: "\xBB", + Rarr: "\u21A0", + rArr: "\u21D2", + rarr: "\u2192", + rarrap: "\u2975", + rarrb: "\u21E5", + rarrbfs: "\u2920", + rarrc: "\u2933", + rarrfs: "\u291E", + rarrhk: "\u21AA", + rarrlp: "\u21AC", + rarrpl: "\u2945", + rarrsim: "\u2974", + Rarrtl: "\u2916", + rarrtl: "\u21A3", + rarrw: "\u219D", + rAtail: "\u291C", + ratail: "\u291A", + ratio: "\u2236", + rationals: "\u211A", + RBarr: "\u2910", + rBarr: "\u290F", + rbarr: "\u290D", + rbbrk: "\u2773", + rbrace: "}", + rbrack: "]", + rbrke: "\u298C", + rbrksld: "\u298E", + rbrkslu: "\u2990", + Rcaron: "\u0158", + rcaron: "\u0159", + Rcedil: "\u0156", + rcedil: "\u0157", + rceil: "\u2309", + rcub: "}", + Rcy: "\u0420", + rcy: "\u0440", + rdca: "\u2937", + rdldhar: "\u2969", + rdquo: "\u201D", + rdquor: "\u201D", + rdsh: "\u21B3", + Re: "\u211C", + real: "\u211C", + realine: "\u211B", + realpart: "\u211C", + reals: "\u211D", + rect: "\u25AD", + REG: "\xAE", + reg: "\xAE", + ReverseElement: "\u220B", + ReverseEquilibrium: "\u21CB", + ReverseUpEquilibrium: "\u296F", + rfisht: "\u297D", + rfloor: "\u230B", + Rfr: "\u211C", + rfr: "\u{1D52F}", + rHar: "\u2964", + rhard: "\u21C1", + rharu: "\u21C0", + rharul: "\u296C", + Rho: "\u03A1", + rho: "\u03C1", + rhov: "\u03F1", + RightAngleBracket: "\u27E9", + RightArrow: "\u2192", + Rightarrow: "\u21D2", + rightarrow: "\u2192", + RightArrowBar: "\u21E5", + RightArrowLeftArrow: "\u21C4", + rightarrowtail: "\u21A3", + RightCeiling: "\u2309", + RightDoubleBracket: "\u27E7", + RightDownTeeVector: "\u295D", + RightDownVector: "\u21C2", + RightDownVectorBar: "\u2955", + RightFloor: "\u230B", + rightharpoondown: "\u21C1", + rightharpoonup: "\u21C0", + rightleftarrows: "\u21C4", + rightleftharpoons: "\u21CC", + rightrightarrows: "\u21C9", + rightsquigarrow: "\u219D", + RightTee: "\u22A2", + RightTeeArrow: "\u21A6", + RightTeeVector: "\u295B", + rightthreetimes: "\u22CC", + RightTriangle: "\u22B3", + RightTriangleBar: "\u29D0", + RightTriangleEqual: "\u22B5", + RightUpDownVector: "\u294F", + RightUpTeeVector: "\u295C", + RightUpVector: "\u21BE", + RightUpVectorBar: "\u2954", + RightVector: "\u21C0", + RightVectorBar: "\u2953", + ring: "\u02DA", + risingdotseq: "\u2253", + rlarr: "\u21C4", + rlhar: "\u21CC", + rlm: "\u200F", + rmoust: "\u23B1", + rmoustache: "\u23B1", + rnmid: "\u2AEE", + roang: "\u27ED", + roarr: "\u21FE", + robrk: "\u27E7", + ropar: "\u2986", + Ropf: "\u211D", + ropf: "\u{1D563}", + roplus: "\u2A2E", + rotimes: "\u2A35", + RoundImplies: "\u2970", + rpar: ")", + rpargt: "\u2994", + rppolint: "\u2A12", + rrarr: "\u21C9", + Rrightarrow: "\u21DB", + rsaquo: "\u203A", + Rscr: "\u211B", + rscr: "\u{1D4C7}", + Rsh: "\u21B1", + rsh: "\u21B1", + rsqb: "]", + rsquo: "\u2019", + rsquor: "\u2019", + rthree: "\u22CC", + rtimes: "\u22CA", + rtri: "\u25B9", + rtrie: "\u22B5", + rtrif: "\u25B8", + rtriltri: "\u29CE", + RuleDelayed: "\u29F4", + ruluhar: "\u2968", + rx: "\u211E", + Sacute: "\u015A", + sacute: "\u015B", + sbquo: "\u201A", + Sc: "\u2ABC", + sc: "\u227B", + scap: "\u2AB8", + Scaron: "\u0160", + scaron: "\u0161", + sccue: "\u227D", + scE: "\u2AB4", + sce: "\u2AB0", + Scedil: "\u015E", + scedil: "\u015F", + Scirc: "\u015C", + scirc: "\u015D", + scnap: "\u2ABA", + scnE: "\u2AB6", + scnsim: "\u22E9", + scpolint: "\u2A13", + scsim: "\u227F", + Scy: "\u0421", + scy: "\u0441", + sdot: "\u22C5", + sdotb: "\u22A1", + sdote: "\u2A66", + searhk: "\u2925", + seArr: "\u21D8", + searr: "\u2198", + searrow: "\u2198", + sect: "\xA7", + semi: ";", + seswar: "\u2929", + setminus: "\u2216", + setmn: "\u2216", + sext: "\u2736", + Sfr: "\u{1D516}", + sfr: "\u{1D530}", + sfrown: "\u2322", + sharp: "\u266F", + SHCHcy: "\u0429", + shchcy: "\u0449", + SHcy: "\u0428", + shcy: "\u0448", + ShortDownArrow: "\u2193", + ShortLeftArrow: "\u2190", + shortmid: "\u2223", + shortparallel: "\u2225", + ShortRightArrow: "\u2192", + ShortUpArrow: "\u2191", + shy: "\xAD", + Sigma: "\u03A3", + sigma: "\u03C3", + sigmaf: "\u03C2", + sigmav: "\u03C2", + sim: "\u223C", + simdot: "\u2A6A", + sime: "\u2243", + simeq: "\u2243", + simg: "\u2A9E", + simgE: "\u2AA0", + siml: "\u2A9D", + simlE: "\u2A9F", + simne: "\u2246", + simplus: "\u2A24", + simrarr: "\u2972", + slarr: "\u2190", + SmallCircle: "\u2218", + smallsetminus: "\u2216", + smashp: "\u2A33", + smeparsl: "\u29E4", + smid: "\u2223", + smile: "\u2323", + smt: "\u2AAA", + smte: "\u2AAC", + smtes: "\u2AAC\uFE00", + SOFTcy: "\u042C", + softcy: "\u044C", + sol: "/", + solb: "\u29C4", + solbar: "\u233F", + Sopf: "\u{1D54A}", + sopf: "\u{1D564}", + spades: "\u2660", + spadesuit: "\u2660", + spar: "\u2225", + sqcap: "\u2293", + sqcaps: "\u2293\uFE00", + sqcup: "\u2294", + sqcups: "\u2294\uFE00", + Sqrt: "\u221A", + sqsub: "\u228F", + sqsube: "\u2291", + sqsubset: "\u228F", + sqsubseteq: "\u2291", + sqsup: "\u2290", + sqsupe: "\u2292", + sqsupset: "\u2290", + sqsupseteq: "\u2292", + squ: "\u25A1", + Square: "\u25A1", + square: "\u25A1", + SquareIntersection: "\u2293", + SquareSubset: "\u228F", + SquareSubsetEqual: "\u2291", + SquareSuperset: "\u2290", + SquareSupersetEqual: "\u2292", + SquareUnion: "\u2294", + squarf: "\u25AA", + squf: "\u25AA", + srarr: "\u2192", + Sscr: "\u{1D4AE}", + sscr: "\u{1D4C8}", + ssetmn: "\u2216", + ssmile: "\u2323", + sstarf: "\u22C6", + Star: "\u22C6", + star: "\u2606", + starf: "\u2605", + straightepsilon: "\u03F5", + straightphi: "\u03D5", + strns: "\xAF", + Sub: "\u22D0", + sub: "\u2282", + subdot: "\u2ABD", + subE: "\u2AC5", + sube: "\u2286", + subedot: "\u2AC3", + submult: "\u2AC1", + subnE: "\u2ACB", + subne: "\u228A", + subplus: "\u2ABF", + subrarr: "\u2979", + Subset: "\u22D0", + subset: "\u2282", + subseteq: "\u2286", + subseteqq: "\u2AC5", + SubsetEqual: "\u2286", + subsetneq: "\u228A", + subsetneqq: "\u2ACB", + subsim: "\u2AC7", + subsub: "\u2AD5", + subsup: "\u2AD3", + succ: "\u227B", + succapprox: "\u2AB8", + succcurlyeq: "\u227D", + Succeeds: "\u227B", + SucceedsEqual: "\u2AB0", + SucceedsSlantEqual: "\u227D", + SucceedsTilde: "\u227F", + succeq: "\u2AB0", + succnapprox: "\u2ABA", + succneqq: "\u2AB6", + succnsim: "\u22E9", + succsim: "\u227F", + SuchThat: "\u220B", + Sum: "\u2211", + sum: "\u2211", + sung: "\u266A", + Sup: "\u22D1", + sup: "\u2283", + sup1: "\xB9", + sup2: "\xB2", + sup3: "\xB3", + supdot: "\u2ABE", + supdsub: "\u2AD8", + supE: "\u2AC6", + supe: "\u2287", + supedot: "\u2AC4", + Superset: "\u2283", + SupersetEqual: "\u2287", + suphsol: "\u27C9", + suphsub: "\u2AD7", + suplarr: "\u297B", + supmult: "\u2AC2", + supnE: "\u2ACC", + supne: "\u228B", + supplus: "\u2AC0", + Supset: "\u22D1", + supset: "\u2283", + supseteq: "\u2287", + supseteqq: "\u2AC6", + supsetneq: "\u228B", + supsetneqq: "\u2ACC", + supsim: "\u2AC8", + supsub: "\u2AD4", + supsup: "\u2AD6", + swarhk: "\u2926", + swArr: "\u21D9", + swarr: "\u2199", + swarrow: "\u2199", + swnwar: "\u292A", + szlig: "\xDF", + Tab: " ", + target: "\u2316", + Tau: "\u03A4", + tau: "\u03C4", + tbrk: "\u23B4", + Tcaron: "\u0164", + tcaron: "\u0165", + Tcedil: "\u0162", + tcedil: "\u0163", + Tcy: "\u0422", + tcy: "\u0442", + tdot: "\u20DB", + telrec: "\u2315", + Tfr: "\u{1D517}", + tfr: "\u{1D531}", + there4: "\u2234", + Therefore: "\u2234", + therefore: "\u2234", + Theta: "\u0398", + theta: "\u03B8", + thetasym: "\u03D1", + thetav: "\u03D1", + thickapprox: "\u2248", + thicksim: "\u223C", + ThickSpace: "\u205F\u200A", + thinsp: "\u2009", + ThinSpace: "\u2009", + thkap: "\u2248", + thksim: "\u223C", + THORN: "\xDE", + thorn: "\xFE", + Tilde: "\u223C", + tilde: "\u02DC", + TildeEqual: "\u2243", + TildeFullEqual: "\u2245", + TildeTilde: "\u2248", + times: "\xD7", + timesb: "\u22A0", + timesbar: "\u2A31", + timesd: "\u2A30", + tint: "\u222D", + toea: "\u2928", + top: "\u22A4", + topbot: "\u2336", + topcir: "\u2AF1", + Topf: "\u{1D54B}", + topf: "\u{1D565}", + topfork: "\u2ADA", + tosa: "\u2929", + tprime: "\u2034", + TRADE: "\u2122", + trade: "\u2122", + triangle: "\u25B5", + triangledown: "\u25BF", + triangleleft: "\u25C3", + trianglelefteq: "\u22B4", + triangleq: "\u225C", + triangleright: "\u25B9", + trianglerighteq: "\u22B5", + tridot: "\u25EC", + trie: "\u225C", + triminus: "\u2A3A", + TripleDot: "\u20DB", + triplus: "\u2A39", + trisb: "\u29CD", + tritime: "\u2A3B", + trpezium: "\u23E2", + Tscr: "\u{1D4AF}", + tscr: "\u{1D4C9}", + TScy: "\u0426", + tscy: "\u0446", + TSHcy: "\u040B", + tshcy: "\u045B", + Tstrok: "\u0166", + tstrok: "\u0167", + twixt: "\u226C", + twoheadleftarrow: "\u219E", + twoheadrightarrow: "\u21A0", + Uacute: "\xDA", + uacute: "\xFA", + Uarr: "\u219F", + uArr: "\u21D1", + uarr: "\u2191", + Uarrocir: "\u2949", + Ubrcy: "\u040E", + ubrcy: "\u045E", + Ubreve: "\u016C", + ubreve: "\u016D", + Ucirc: "\xDB", + ucirc: "\xFB", + Ucy: "\u0423", + ucy: "\u0443", + udarr: "\u21C5", + Udblac: "\u0170", + udblac: "\u0171", + udhar: "\u296E", + ufisht: "\u297E", + Ufr: "\u{1D518}", + ufr: "\u{1D532}", + Ugrave: "\xD9", + ugrave: "\xF9", + uHar: "\u2963", + uharl: "\u21BF", + uharr: "\u21BE", + uhblk: "\u2580", + ulcorn: "\u231C", + ulcorner: "\u231C", + ulcrop: "\u230F", + ultri: "\u25F8", + Umacr: "\u016A", + umacr: "\u016B", + uml: "\xA8", + UnderBar: "_", + UnderBrace: "\u23DF", + UnderBracket: "\u23B5", + UnderParenthesis: "\u23DD", + Union: "\u22C3", + UnionPlus: "\u228E", + Uogon: "\u0172", + uogon: "\u0173", + Uopf: "\u{1D54C}", + uopf: "\u{1D566}", + UpArrow: "\u2191", + Uparrow: "\u21D1", + uparrow: "\u2191", + UpArrowBar: "\u2912", + UpArrowDownArrow: "\u21C5", + UpDownArrow: "\u2195", + Updownarrow: "\u21D5", + updownarrow: "\u2195", + UpEquilibrium: "\u296E", + upharpoonleft: "\u21BF", + upharpoonright: "\u21BE", + uplus: "\u228E", + UpperLeftArrow: "\u2196", + UpperRightArrow: "\u2197", + Upsi: "\u03D2", + upsi: "\u03C5", + upsih: "\u03D2", + Upsilon: "\u03A5", + upsilon: "\u03C5", + UpTee: "\u22A5", + UpTeeArrow: "\u21A5", + upuparrows: "\u21C8", + urcorn: "\u231D", + urcorner: "\u231D", + urcrop: "\u230E", + Uring: "\u016E", + uring: "\u016F", + urtri: "\u25F9", + Uscr: "\u{1D4B0}", + uscr: "\u{1D4CA}", + utdot: "\u22F0", + Utilde: "\u0168", + utilde: "\u0169", + utri: "\u25B5", + utrif: "\u25B4", + uuarr: "\u21C8", + Uuml: "\xDC", + uuml: "\xFC", + uwangle: "\u29A7", + vangrt: "\u299C", + varepsilon: "\u03F5", + varkappa: "\u03F0", + varnothing: "\u2205", + varphi: "\u03D5", + varpi: "\u03D6", + varpropto: "\u221D", + vArr: "\u21D5", + varr: "\u2195", + varrho: "\u03F1", + varsigma: "\u03C2", + varsubsetneq: "\u228A\uFE00", + varsubsetneqq: "\u2ACB\uFE00", + varsupsetneq: "\u228B\uFE00", + varsupsetneqq: "\u2ACC\uFE00", + vartheta: "\u03D1", + vartriangleleft: "\u22B2", + vartriangleright: "\u22B3", + Vbar: "\u2AEB", + vBar: "\u2AE8", + vBarv: "\u2AE9", + Vcy: "\u0412", + vcy: "\u0432", + VDash: "\u22AB", + Vdash: "\u22A9", + vDash: "\u22A8", + vdash: "\u22A2", + Vdashl: "\u2AE6", + Vee: "\u22C1", + vee: "\u2228", + veebar: "\u22BB", + veeeq: "\u225A", + vellip: "\u22EE", + Verbar: "\u2016", + verbar: "|", + Vert: "\u2016", + vert: "|", + VerticalBar: "\u2223", + VerticalLine: "|", + VerticalSeparator: "\u2758", + VerticalTilde: "\u2240", + VeryThinSpace: "\u200A", + Vfr: "\u{1D519}", + vfr: "\u{1D533}", + vltri: "\u22B2", + vnsub: "\u2282\u20D2", + vnsup: "\u2283\u20D2", + Vopf: "\u{1D54D}", + vopf: "\u{1D567}", + vprop: "\u221D", + vrtri: "\u22B3", + Vscr: "\u{1D4B1}", + vscr: "\u{1D4CB}", + vsubnE: "\u2ACB\uFE00", + vsubne: "\u228A\uFE00", + vsupnE: "\u2ACC\uFE00", + vsupne: "\u228B\uFE00", + Vvdash: "\u22AA", + vzigzag: "\u299A", + Wcirc: "\u0174", + wcirc: "\u0175", + wedbar: "\u2A5F", + Wedge: "\u22C0", + wedge: "\u2227", + wedgeq: "\u2259", + weierp: "\u2118", + Wfr: "\u{1D51A}", + wfr: "\u{1D534}", + Wopf: "\u{1D54E}", + wopf: "\u{1D568}", + wp: "\u2118", + wr: "\u2240", + wreath: "\u2240", + Wscr: "\u{1D4B2}", + wscr: "\u{1D4CC}", + xcap: "\u22C2", + xcirc: "\u25EF", + xcup: "\u22C3", + xdtri: "\u25BD", + Xfr: "\u{1D51B}", + xfr: "\u{1D535}", + xhArr: "\u27FA", + xharr: "\u27F7", + Xi: "\u039E", + xi: "\u03BE", + xlArr: "\u27F8", + xlarr: "\u27F5", + xmap: "\u27FC", + xnis: "\u22FB", + xodot: "\u2A00", + Xopf: "\u{1D54F}", + xopf: "\u{1D569}", + xoplus: "\u2A01", + xotime: "\u2A02", + xrArr: "\u27F9", + xrarr: "\u27F6", + Xscr: "\u{1D4B3}", + xscr: "\u{1D4CD}", + xsqcup: "\u2A06", + xuplus: "\u2A04", + xutri: "\u25B3", + xvee: "\u22C1", + xwedge: "\u22C0", + Yacute: "\xDD", + yacute: "\xFD", + YAcy: "\u042F", + yacy: "\u044F", + Ycirc: "\u0176", + ycirc: "\u0177", + Ycy: "\u042B", + ycy: "\u044B", + yen: "\xA5", + Yfr: "\u{1D51C}", + yfr: "\u{1D536}", + YIcy: "\u0407", + yicy: "\u0457", + Yopf: "\u{1D550}", + yopf: "\u{1D56A}", + Yscr: "\u{1D4B4}", + yscr: "\u{1D4CE}", + YUcy: "\u042E", + yucy: "\u044E", + Yuml: "\u0178", + yuml: "\xFF", + Zacute: "\u0179", + zacute: "\u017A", + Zcaron: "\u017D", + zcaron: "\u017E", + Zcy: "\u0417", + zcy: "\u0437", + Zdot: "\u017B", + zdot: "\u017C", + zeetrf: "\u2128", + ZeroWidthSpace: "\u200B", + Zeta: "\u0396", + zeta: "\u03B6", + Zfr: "\u2128", + zfr: "\u{1D537}", + ZHcy: "\u0416", + zhcy: "\u0436", + zigrarr: "\u21DD", + Zopf: "\u2124", + zopf: "\u{1D56B}", + Zscr: "\u{1D4B5}", + zscr: "\u{1D4CF}", + zwj: "\u200D", + zwnj: "\u200C" + }); + exports2.entityMap = exports2.HTML_ENTITIES; + } +}); + +// ../../node_modules/@xmldom/xmldom/lib/sax.js +var require_sax = __commonJS({ + "../../node_modules/@xmldom/xmldom/lib/sax.js"(exports2) { + var NAMESPACE = require_conventions().NAMESPACE; + var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; + var nameChar = new RegExp("[\\-\\.0-9" + nameStartChar.source.slice(1, -1) + "\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"); + var tagNamePattern = new RegExp("^" + nameStartChar.source + nameChar.source + "*(?::" + nameStartChar.source + nameChar.source + "*)?$"); + var S_TAG = 0; + var S_ATTR = 1; + var S_ATTR_SPACE = 2; + var S_EQ = 3; + var S_ATTR_NOQUOT_VALUE = 4; + var S_ATTR_END = 5; + var S_TAG_SPACE = 6; + var S_TAG_CLOSE = 7; + function ParseError(message, locator) { + this.message = message; + this.locator = locator; + if (Error.captureStackTrace) Error.captureStackTrace(this, ParseError); + } + ParseError.prototype = new Error(); + ParseError.prototype.name = ParseError.name; + function XMLReader() { + } + XMLReader.prototype = { + parse: function(source, defaultNSMap, entityMap) { + var domBuilder = this.domBuilder; + domBuilder.startDocument(); + _copy(defaultNSMap, defaultNSMap = {}); + parse( + source, + defaultNSMap, + entityMap, + domBuilder, + this.errorHandler + ); + domBuilder.endDocument(); + } + }; + function parse(source, defaultNSMapCopy, entityMap, domBuilder, errorHandler) { + function fixedFromCharCode(code) { + if (code > 65535) { + code -= 65536; + var surrogate1 = 55296 + (code >> 10), surrogate2 = 56320 + (code & 1023); + return String.fromCharCode(surrogate1, surrogate2); + } else { + return String.fromCharCode(code); + } + } + function entityReplacer(a2) { + var k = a2.slice(1, -1); + if (Object.hasOwnProperty.call(entityMap, k)) { + return entityMap[k]; + } else if (k.charAt(0) === "#") { + return fixedFromCharCode(parseInt(k.substr(1).replace("x", "0x"))); + } else { + errorHandler.error("entity not found:" + a2); + return a2; + } + } + function appendText(end2) { + if (end2 > start) { + var xt = source.substring(start, end2).replace(/&#?\w+;/g, entityReplacer); + locator && position(start); + domBuilder.characters(xt, 0, end2 - start); + start = end2; + } + } + function position(p, m) { + while (p >= lineEnd && (m = linePattern.exec(source))) { + lineStart = m.index; + lineEnd = lineStart + m[0].length; + locator.lineNumber++; + } + locator.columnNumber = p - lineStart + 1; + } + var lineStart = 0; + var lineEnd = 0; + var linePattern = /.*(?:\r\n?|\n)|.*$/g; + var locator = domBuilder.locator; + var parseStack = [{ currentNSMap: defaultNSMapCopy }]; + var closeMap = {}; + var start = 0; + while (true) { + try { + var tagStart = source.indexOf("<", start); + if (tagStart < 0) { + if (!source.substr(start).match(/^\s*$/)) { + var doc = domBuilder.doc; + var text = doc.createTextNode(source.substr(start)); + doc.appendChild(text); + domBuilder.currentElement = text; + } + return; + } + if (tagStart > start) { + appendText(tagStart); + } + switch (source.charAt(tagStart + 1)) { + case "/": + var end = source.indexOf(">", tagStart + 3); + var tagName = source.substring(tagStart + 2, end).replace(/[ \t\n\r]+$/g, ""); + var config = parseStack.pop(); + if (end < 0) { + tagName = source.substring(tagStart + 2).replace(/[\s<].*/, ""); + errorHandler.error("end tag name: " + tagName + " is not complete:" + config.tagName); + end = tagStart + 1 + tagName.length; + } else if (tagName.match(/\s start) { + start = end; + } else { + appendText(Math.max(tagStart, start) + 1); + } + } + } + function copyLocator(f, t) { + t.lineNumber = f.lineNumber; + t.columnNumber = f.columnNumber; + return t; + } + function parseElementStartPart(source, start, el, currentNSMap, entityReplacer, errorHandler) { + function addAttribute(qname, value2, startIndex) { + if (el.attributeNames.hasOwnProperty(qname)) { + errorHandler.fatalError("Attribute " + qname + " redefined"); + } + el.addValue( + qname, + // @see https://www.w3.org/TR/xml/#AVNormalize + // since the xmldom sax parser does not "interpret" DTD the following is not implemented: + // - recursive replacement of (DTD) entity references + // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA + value2.replace(/[\t\n\r]/g, " ").replace(/&#?\w+;/g, entityReplacer), + startIndex + ); + } + var attrName; + var value; + var p = ++start; + var s = S_TAG; + while (true) { + var c = source.charAt(p); + switch (c) { + case "=": + if (s === S_ATTR) { + attrName = source.slice(start, p); + s = S_EQ; + } else if (s === S_ATTR_SPACE) { + s = S_EQ; + } else { + throw new Error("attribute equal must after attrName"); + } + break; + case "'": + case '"': + if (s === S_EQ || s === S_ATTR) { + if (s === S_ATTR) { + errorHandler.warning('attribute value must after "="'); + attrName = source.slice(start, p); + } + start = p + 1; + p = source.indexOf(c, start); + if (p > 0) { + value = source.slice(start, p); + addAttribute(attrName, value, start - 1); + s = S_ATTR_END; + } else { + throw new Error("attribute value no end '" + c + "' match"); + } + } else if (s == S_ATTR_NOQUOT_VALUE) { + value = source.slice(start, p); + addAttribute(attrName, value, start); + errorHandler.warning('attribute "' + attrName + '" missed start quot(' + c + ")!!"); + start = p + 1; + s = S_ATTR_END; + } else { + throw new Error('attribute value must after "="'); + } + break; + case "/": + switch (s) { + case S_TAG: + el.setTagName(source.slice(start, p)); + case S_ATTR_END: + case S_TAG_SPACE: + case S_TAG_CLOSE: + s = S_TAG_CLOSE; + el.closed = true; + case S_ATTR_NOQUOT_VALUE: + case S_ATTR: + break; + case S_ATTR_SPACE: + el.closed = true; + break; + default: + throw new Error("attribute invalid close char('/')"); + } + break; + case "": + errorHandler.error("unexpected end of input"); + if (s == S_TAG) { + el.setTagName(source.slice(start, p)); + } + return p; + case ">": + switch (s) { + case S_TAG: + el.setTagName(source.slice(start, p)); + case S_ATTR_END: + case S_TAG_SPACE: + case S_TAG_CLOSE: + break; + case S_ATTR_NOQUOT_VALUE: + case S_ATTR: + value = source.slice(start, p); + if (value.slice(-1) === "/") { + el.closed = true; + value = value.slice(0, -1); + } + case S_ATTR_SPACE: + if (s === S_ATTR_SPACE) { + value = attrName; + } + if (s == S_ATTR_NOQUOT_VALUE) { + errorHandler.warning('attribute "' + value + '" missed quot(")!'); + addAttribute(attrName, value, start); + } else { + if (!NAMESPACE.isHTML(currentNSMap[""]) || !value.match(/^(?:disabled|checked|selected)$/i)) { + errorHandler.warning('attribute "' + value + '" missed value!! "' + value + '" instead!!'); + } + addAttribute(value, value, start); + } + break; + case S_EQ: + throw new Error("attribute value missed!!"); + } + return p; + case "\x80": + c = " "; + default: + if (c <= " ") { + switch (s) { + case S_TAG: + el.setTagName(source.slice(start, p)); + s = S_TAG_SPACE; + break; + case S_ATTR: + attrName = source.slice(start, p); + s = S_ATTR_SPACE; + break; + case S_ATTR_NOQUOT_VALUE: + var value = source.slice(start, p); + errorHandler.warning('attribute "' + value + '" missed quot(")!!'); + addAttribute(attrName, value, start); + case S_ATTR_END: + s = S_TAG_SPACE; + break; + } + } else { + switch (s) { + case S_ATTR_SPACE: + var tagName = el.tagName; + if (!NAMESPACE.isHTML(currentNSMap[""]) || !attrName.match(/^(?:disabled|checked|selected)$/i)) { + errorHandler.warning('attribute "' + attrName + '" missed value!! "' + attrName + '" instead2!!'); + } + addAttribute(attrName, attrName, start); + start = p; + s = S_ATTR; + break; + case S_ATTR_END: + errorHandler.warning('attribute space is required"' + attrName + '"!!'); + case S_TAG_SPACE: + s = S_ATTR; + start = p; + break; + case S_EQ: + s = S_ATTR_NOQUOT_VALUE; + start = p; + break; + case S_TAG_CLOSE: + throw new Error("elements closed character '/' and '>' must be connected to"); + } + } + } + p++; + } + } + function appendElement(el, domBuilder, currentNSMap) { + var tagName = el.tagName; + var localNSMap = null; + var i = el.length; + while (i--) { + var a = el[i]; + var qName = a.qName; + var value = a.value; + var nsp = qName.indexOf(":"); + if (nsp > 0) { + var prefix = a.prefix = qName.slice(0, nsp); + var localName = qName.slice(nsp + 1); + var nsPrefix = prefix === "xmlns" && localName; + } else { + localName = qName; + prefix = null; + nsPrefix = qName === "xmlns" && ""; + } + a.localName = localName; + if (nsPrefix !== false) { + if (localNSMap == null) { + localNSMap = {}; + _copy(currentNSMap, currentNSMap = {}); + } + currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; + a.uri = NAMESPACE.XMLNS; + domBuilder.startPrefixMapping(nsPrefix, value); + } + } + var i = el.length; + while (i--) { + a = el[i]; + var prefix = a.prefix; + if (prefix) { + if (prefix === "xml") { + a.uri = NAMESPACE.XML; + } + if (prefix !== "xmlns") { + a.uri = currentNSMap[prefix || ""]; + } + } + } + var nsp = tagName.indexOf(":"); + if (nsp > 0) { + prefix = el.prefix = tagName.slice(0, nsp); + localName = el.localName = tagName.slice(nsp + 1); + } else { + prefix = null; + localName = el.localName = tagName; + } + var ns = el.uri = currentNSMap[prefix || ""]; + domBuilder.startElement(ns, localName, tagName, el); + if (el.closed) { + domBuilder.endElement(ns, localName, tagName); + if (localNSMap) { + for (prefix in localNSMap) { + if (Object.prototype.hasOwnProperty.call(localNSMap, prefix)) { + domBuilder.endPrefixMapping(prefix); + } + } + } + } else { + el.currentNSMap = currentNSMap; + el.localNSMap = localNSMap; + return true; + } + } + function parseHtmlSpecialContent(source, elStartEnd, tagName, entityReplacer, domBuilder) { + if (/^(?:script|textarea)$/i.test(tagName)) { + var elEndStart = source.indexOf("", elStartEnd); + var text = source.substring(elStartEnd + 1, elEndStart); + if (/[&<]/.test(text)) { + if (/^script$/i.test(tagName)) { + domBuilder.characters(text, 0, text.length); + return elEndStart; + } + text = text.replace(/&#?\w+;/g, entityReplacer); + domBuilder.characters(text, 0, text.length); + return elEndStart; + } + } + return elStartEnd + 1; + } + function fixSelfClosed(source, elStartEnd, tagName, closeMap) { + var pos = closeMap[tagName]; + if (pos == null) { + pos = source.lastIndexOf(""); + if (pos < elStartEnd) { + pos = source.lastIndexOf("", start + 4); + if (end > start) { + domBuilder.comment(source, start + 4, end - start - 4); + return end + 3; + } else { + errorHandler.error("Unclosed comment"); + return -1; + } + } else { + return -1; + } + default: + if (source.substr(start + 3, 6) == "CDATA[") { + var end = source.indexOf("]]>", start + 9); + domBuilder.startCDATA(); + domBuilder.characters(source, start + 9, end - start - 9); + domBuilder.endCDATA(); + return end + 3; + } + var matchs = split(source, start); + var len = matchs.length; + if (len > 1 && /!doctype/i.test(matchs[0][0])) { + var name2 = matchs[1][0]; + var pubid = false; + var sysid = false; + if (len > 3) { + if (/^public$/i.test(matchs[2][0])) { + pubid = matchs[3][0]; + sysid = len > 4 && matchs[4][0]; + } else if (/^system$/i.test(matchs[2][0])) { + sysid = matchs[3][0]; + } + } + var lastMatch = matchs[len - 1]; + domBuilder.startDTD(name2, pubid, sysid); + domBuilder.endDTD(); + return lastMatch.index + lastMatch[0].length; + } + } + return -1; + } + function parseInstruction(source, start, domBuilder) { + var end = source.indexOf("?>", start); + if (end) { + var match = source.substring(start, end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/); + if (match) { + var len = match[0].length; + domBuilder.processingInstruction(match[1], match[2]); + return end + 2; + } else { + return -1; + } + } + return -1; + } + function ElementAttributes() { + this.attributeNames = {}; + } + ElementAttributes.prototype = { + setTagName: function(tagName) { + if (!tagNamePattern.test(tagName)) { + throw new Error("invalid tagName:" + tagName); + } + this.tagName = tagName; + }, + addValue: function(qName, value, offset) { + if (!tagNamePattern.test(qName)) { + throw new Error("invalid attribute:" + qName); + } + this.attributeNames[qName] = this.length; + this[this.length++] = { qName, value, offset }; + }, + length: 0, + getLocalName: function(i) { + return this[i].localName; + }, + getLocator: function(i) { + return this[i].locator; + }, + getQName: function(i) { + return this[i].qName; + }, + getURI: function(i) { + return this[i].uri; + }, + getValue: function(i) { + return this[i].value; + } + // ,getIndex:function(uri, localName)){ + // if(localName){ + // + // }else{ + // var qName = uri + // } + // }, + // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))}, + // getType:function(uri,localName){} + // getType:function(i){}, + }; + function split(source, start) { + var match; + var buf = []; + var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g; + reg.lastIndex = start; + reg.exec(source); + while (match = reg.exec(source)) { + buf.push(match); + if (match[1]) return buf; + } + } + exports2.XMLReader = XMLReader; + exports2.ParseError = ParseError; + } +}); + +// ../../node_modules/@xmldom/xmldom/lib/dom-parser.js +var require_dom_parser = __commonJS({ + "../../node_modules/@xmldom/xmldom/lib/dom-parser.js"(exports2) { + var conventions = require_conventions(); + var dom = require_dom(); + var entities = require_entities(); + var sax = require_sax(); + var DOMImplementation = dom.DOMImplementation; + var NAMESPACE = conventions.NAMESPACE; + var ParseError = sax.ParseError; + var XMLReader = sax.XMLReader; + function normalizeLineEndings(input) { + return input.replace(/\r[\n\u0085]/g, "\n").replace(/[\r\u0085\u2028]/g, "\n"); + } + function DOMParser2(options) { + this.options = options || { locator: {} }; + } + DOMParser2.prototype.parseFromString = function(source, mimeType) { + var options = this.options; + var sax2 = new XMLReader(); + var domBuilder = options.domBuilder || new DOMHandler(); + var errorHandler = options.errorHandler; + var locator = options.locator; + var defaultNSMap = options.xmlns || {}; + var isHTML = /\/x?html?$/.test(mimeType); + var entityMap = isHTML ? entities.HTML_ENTITIES : entities.XML_ENTITIES; + if (locator) { + domBuilder.setDocumentLocator(locator); + } + sax2.errorHandler = buildErrorHandler(errorHandler, domBuilder, locator); + sax2.domBuilder = options.domBuilder || domBuilder; + if (isHTML) { + defaultNSMap[""] = NAMESPACE.HTML; + } + defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML; + var normalize = options.normalizeLineEndings || normalizeLineEndings; + if (source && typeof source === "string") { + sax2.parse( + normalize(source), + defaultNSMap, + entityMap + ); + } else { + sax2.errorHandler.error("invalid doc source"); + } + return domBuilder.doc; + }; + function buildErrorHandler(errorImpl, domBuilder, locator) { + if (!errorImpl) { + if (domBuilder instanceof DOMHandler) { + return domBuilder; + } + errorImpl = domBuilder; + } + var errorHandler = {}; + var isCallback = errorImpl instanceof Function; + locator = locator || {}; + function build(key) { + var fn2 = errorImpl[key]; + if (!fn2 && isCallback) { + fn2 = errorImpl.length == 2 ? function(msg) { + errorImpl(key, msg); + } : errorImpl; + } + errorHandler[key] = fn2 && function(msg) { + fn2("[xmldom " + key + "] " + msg + _locator(locator)); + } || function() { + }; + } + build("warning"); + build("error"); + build("fatalError"); + return errorHandler; + } + function DOMHandler() { + this.cdata = false; + } + function position(locator, node) { + node.lineNumber = locator.lineNumber; + node.columnNumber = locator.columnNumber; + } + DOMHandler.prototype = { + startDocument: function() { + this.doc = new DOMImplementation().createDocument(null, null, null); + if (this.locator) { + this.doc.documentURI = this.locator.systemId; + } + }, + startElement: function(namespaceURI, localName, qName, attrs) { + var doc = this.doc; + var el = doc.createElementNS(namespaceURI, qName || localName); + var len = attrs.length; + appendElement(this, el); + this.currentElement = el; + this.locator && position(this.locator, el); + for (var i = 0; i < len; i++) { + var namespaceURI = attrs.getURI(i); + var value = attrs.getValue(i); + var qName = attrs.getQName(i); + var attr = doc.createAttributeNS(namespaceURI, qName); + this.locator && position(attrs.getLocator(i), attr); + attr.value = attr.nodeValue = value; + el.setAttributeNode(attr); + } + }, + endElement: function(namespaceURI, localName, qName) { + var current = this.currentElement; + var tagName = current.tagName; + this.currentElement = current.parentNode; + }, + startPrefixMapping: function(prefix, uri) { + }, + endPrefixMapping: function(prefix) { + }, + processingInstruction: function(target, data) { + var ins = this.doc.createProcessingInstruction(target, data); + this.locator && position(this.locator, ins); + appendElement(this, ins); + }, + ignorableWhitespace: function(ch, start, length) { + }, + characters: function(chars, start, length) { + chars = _toString.apply(this, arguments); + if (chars) { + if (this.cdata) { + var charNode = this.doc.createCDATASection(chars); + } else { + var charNode = this.doc.createTextNode(chars); + } + if (this.currentElement) { + this.currentElement.appendChild(charNode); + } else if (/^\s*$/.test(chars)) { + this.doc.appendChild(charNode); + } + this.locator && position(this.locator, charNode); + } + }, + skippedEntity: function(name2) { + }, + endDocument: function() { + this.doc.normalize(); + }, + setDocumentLocator: function(locator) { + if (this.locator = locator) { + locator.lineNumber = 0; + } + }, + //LexicalHandler + comment: function(chars, start, length) { + chars = _toString.apply(this, arguments); + var comm = this.doc.createComment(chars); + this.locator && position(this.locator, comm); + appendElement(this, comm); + }, + startCDATA: function() { + this.cdata = true; + }, + endCDATA: function() { + this.cdata = false; + }, + startDTD: function(name2, publicId, systemId) { + var impl = this.doc.implementation; + if (impl && impl.createDocumentType) { + var dt = impl.createDocumentType(name2, publicId, systemId); + this.locator && position(this.locator, dt); + appendElement(this, dt); + this.doc.doctype = dt; + } + }, + /** + * @see org.xml.sax.ErrorHandler + * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html + */ + warning: function(error) { + console.warn("[xmldom warning] " + error, _locator(this.locator)); + }, + error: function(error) { + console.error("[xmldom error] " + error, _locator(this.locator)); + }, + fatalError: function(error) { + throw new ParseError(error, this.locator); + } + }; + function _locator(l) { + if (l) { + return "\n@" + (l.systemId || "") + "#[line:" + l.lineNumber + ",col:" + l.columnNumber + "]"; + } + } + function _toString(chars, start, length) { + if (typeof chars == "string") { + return chars.substr(start, length); + } else { + if (chars.length >= start + length || start) { + return new java.lang.String(chars, start, length) + ""; + } + return chars; + } + } + "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g, function(key) { + DOMHandler.prototype[key] = function() { + return null; + }; + }); + function appendElement(hander, node) { + if (!hander.currentElement) { + hander.doc.appendChild(node); + } else { + hander.currentElement.appendChild(node); + } + } + exports2.__DOMHandler = DOMHandler; + exports2.normalizeLineEndings = normalizeLineEndings; + exports2.DOMParser = DOMParser2; + } +}); + +// ../../node_modules/@xmldom/xmldom/lib/index.js +var require_lib = __commonJS({ + "../../node_modules/@xmldom/xmldom/lib/index.js"(exports2) { + var dom = require_dom(); + exports2.DOMImplementation = dom.DOMImplementation; + exports2.XMLSerializer = dom.XMLSerializer; + exports2.DOMParser = require_dom_parser().DOMParser; + } +}); + +// ../../node_modules/xpath/xpath.js +var require_xpath = __commonJS({ + "../../node_modules/xpath/xpath.js"(exports2) { + var xpath2 = typeof exports2 === "undefined" ? {} : exports2; + (function(exports3) { + "use strict"; + var NAMESPACE_NODE_NODETYPE = "__namespace"; + var isNil = function(x) { + return x === null || x === void 0; + }; + var isValidNodeType = function(nodeType) { + return nodeType === NAMESPACE_NODE_NODETYPE || Number.isInteger(nodeType) && nodeType >= 1 && nodeType <= 11; + }; + var isNodeLike = function(value) { + return value && isValidNodeType(value.nodeType) && typeof value.nodeName === "string"; + }; + function curry(func) { + var slice = Array.prototype.slice, totalargs = func.length, partial = function(args, fn3) { + return function() { + return fn3.apply(this, args.concat(slice.call(arguments))); + }; + }, fn2 = function() { + var args = slice.call(arguments); + return args.length < totalargs ? partial(args, fn2) : func.apply(this, slice.apply(arguments, [0, totalargs])); + }; + return fn2; + } + var forEach = function(f, xs) { + for (var i = 0; i < xs.length; i += 1) { + f(xs[i], i, xs); + } + }; + var reduce = function(f, seed, xs) { + var acc = seed; + forEach(function(x, i) { + acc = f(acc, x, i); + }, xs); + return acc; + }; + var map = function(f, xs) { + var mapped = new Array(xs.length); + forEach(function(x, i) { + mapped[i] = f(x); + }, xs); + return mapped; + }; + var filter = function(f, xs) { + var filtered = []; + forEach(function(x, i) { + if (f(x, i)) { + filtered.push(x); + } + }, xs); + return filtered; + }; + var includes = function(values, value) { + for (var i = 0; i < values.length; i += 1) { + if (values[i] === value) { + return true; + } + } + return false; + }; + function always(value) { + return function() { + return value; + }; + } + function toString(x) { + return x.toString(); + } + var join = function(s, xs) { + return xs.join(s); + }; + var wrap = function(pref, suf, str) { + return pref + str + suf; + }; + var prototypeConcat = Array.prototype.concat; + var sortNodes = function(nodes, reverse) { + var ns = new XNodeSet(); + ns.addArray(nodes); + var sorted = ns.toArray(); + return reverse ? sorted.reverse() : sorted; + }; + var MAX_ARGUMENT_LENGTH = 32767; + function flatten(arr) { + var result = []; + for (var start = 0; start < arr.length; start += MAX_ARGUMENT_LENGTH) { + var chunk = arr.slice(start, start + MAX_ARGUMENT_LENGTH); + result = prototypeConcat.apply(result, chunk); + } + return result; + } + function assign(target, varArgs) { + var to = Object(target); + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + if (nextSource != null) { + for (var nextKey in nextSource) { + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; + } + var NodeTypes = { + ELEMENT_NODE: 1, + ATTRIBUTE_NODE: 2, + TEXT_NODE: 3, + CDATA_SECTION_NODE: 4, + PROCESSING_INSTRUCTION_NODE: 7, + COMMENT_NODE: 8, + DOCUMENT_NODE: 9, + DOCUMENT_TYPE_NODE: 10, + DOCUMENT_FRAGMENT_NODE: 11, + NAMESPACE_NODE: NAMESPACE_NODE_NODETYPE + }; + XPathParser.prototype = new Object(); + XPathParser.prototype.constructor = XPathParser; + XPathParser.superclass = Object.prototype; + function XPathParser() { + this.init(); + } + XPathParser.prototype.init = function() { + this.reduceActions = []; + this.reduceActions[3] = function(rhs) { + return new OrOperation(rhs[0], rhs[2]); + }; + this.reduceActions[5] = function(rhs) { + return new AndOperation(rhs[0], rhs[2]); + }; + this.reduceActions[7] = function(rhs) { + return new EqualsOperation(rhs[0], rhs[2]); + }; + this.reduceActions[8] = function(rhs) { + return new NotEqualOperation(rhs[0], rhs[2]); + }; + this.reduceActions[10] = function(rhs) { + return new LessThanOperation(rhs[0], rhs[2]); + }; + this.reduceActions[11] = function(rhs) { + return new GreaterThanOperation(rhs[0], rhs[2]); + }; + this.reduceActions[12] = function(rhs) { + return new LessThanOrEqualOperation(rhs[0], rhs[2]); + }; + this.reduceActions[13] = function(rhs) { + return new GreaterThanOrEqualOperation(rhs[0], rhs[2]); + }; + this.reduceActions[15] = function(rhs) { + return new PlusOperation(rhs[0], rhs[2]); + }; + this.reduceActions[16] = function(rhs) { + return new MinusOperation(rhs[0], rhs[2]); + }; + this.reduceActions[18] = function(rhs) { + return new MultiplyOperation(rhs[0], rhs[2]); + }; + this.reduceActions[19] = function(rhs) { + return new DivOperation(rhs[0], rhs[2]); + }; + this.reduceActions[20] = function(rhs) { + return new ModOperation(rhs[0], rhs[2]); + }; + this.reduceActions[22] = function(rhs) { + return new UnaryMinusOperation(rhs[1]); + }; + this.reduceActions[24] = function(rhs) { + return new BarOperation(rhs[0], rhs[2]); + }; + this.reduceActions[25] = function(rhs) { + return new PathExpr(void 0, void 0, rhs[0]); + }; + this.reduceActions[27] = function(rhs) { + rhs[0].locationPath = rhs[2]; + return rhs[0]; + }; + this.reduceActions[28] = function(rhs) { + rhs[0].locationPath = rhs[2]; + rhs[0].locationPath.steps.unshift(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, [])); + return rhs[0]; + }; + this.reduceActions[29] = function(rhs) { + return new PathExpr(rhs[0], [], void 0); + }; + this.reduceActions[30] = function(rhs) { + if (Utilities.instance_of(rhs[0], PathExpr)) { + if (rhs[0].filterPredicates == void 0) { + rhs[0].filterPredicates = []; + } + rhs[0].filterPredicates.push(rhs[1]); + return rhs[0]; + } else { + return new PathExpr(rhs[0], [rhs[1]], void 0); + } + }; + this.reduceActions[32] = function(rhs) { + return rhs[1]; + }; + this.reduceActions[33] = function(rhs) { + return new XString(rhs[0]); + }; + this.reduceActions[34] = function(rhs) { + return new XNumber(rhs[0]); + }; + this.reduceActions[36] = function(rhs) { + return new FunctionCall(rhs[0], []); + }; + this.reduceActions[37] = function(rhs) { + return new FunctionCall(rhs[0], rhs[2]); + }; + this.reduceActions[38] = function(rhs) { + return [rhs[0]]; + }; + this.reduceActions[39] = function(rhs) { + rhs[2].unshift(rhs[0]); + return rhs[2]; + }; + this.reduceActions[43] = function(rhs) { + return new LocationPath(true, []); + }; + this.reduceActions[44] = function(rhs) { + rhs[1].absolute = true; + return rhs[1]; + }; + this.reduceActions[46] = function(rhs) { + return new LocationPath(false, [rhs[0]]); + }; + this.reduceActions[47] = function(rhs) { + rhs[0].steps.push(rhs[2]); + return rhs[0]; + }; + this.reduceActions[49] = function(rhs) { + return new Step(rhs[0], rhs[1], []); + }; + this.reduceActions[50] = function(rhs) { + return new Step(Step.CHILD, rhs[0], []); + }; + this.reduceActions[51] = function(rhs) { + return new Step(rhs[0], rhs[1], rhs[2]); + }; + this.reduceActions[52] = function(rhs) { + return new Step(Step.CHILD, rhs[0], rhs[1]); + }; + this.reduceActions[54] = function(rhs) { + return [rhs[0]]; + }; + this.reduceActions[55] = function(rhs) { + rhs[1].unshift(rhs[0]); + return rhs[1]; + }; + this.reduceActions[56] = function(rhs) { + if (rhs[0] == "ancestor") { + return Step.ANCESTOR; + } else if (rhs[0] == "ancestor-or-self") { + return Step.ANCESTORORSELF; + } else if (rhs[0] == "attribute") { + return Step.ATTRIBUTE; + } else if (rhs[0] == "child") { + return Step.CHILD; + } else if (rhs[0] == "descendant") { + return Step.DESCENDANT; + } else if (rhs[0] == "descendant-or-self") { + return Step.DESCENDANTORSELF; + } else if (rhs[0] == "following") { + return Step.FOLLOWING; + } else if (rhs[0] == "following-sibling") { + return Step.FOLLOWINGSIBLING; + } else if (rhs[0] == "namespace") { + return Step.NAMESPACE; + } else if (rhs[0] == "parent") { + return Step.PARENT; + } else if (rhs[0] == "preceding") { + return Step.PRECEDING; + } else if (rhs[0] == "preceding-sibling") { + return Step.PRECEDINGSIBLING; + } else if (rhs[0] == "self") { + return Step.SELF; + } + return -1; + }; + this.reduceActions[57] = function(rhs) { + return Step.ATTRIBUTE; + }; + this.reduceActions[59] = function(rhs) { + if (rhs[0] == "comment") { + return NodeTest.commentTest; + } else if (rhs[0] == "text") { + return NodeTest.textTest; + } else if (rhs[0] == "processing-instruction") { + return NodeTest.anyPiTest; + } else if (rhs[0] == "node") { + return NodeTest.nodeTest; + } + return new NodeTest(-1, void 0); + }; + this.reduceActions[60] = function(rhs) { + return new NodeTest.PITest(rhs[2]); + }; + this.reduceActions[61] = function(rhs) { + return rhs[1]; + }; + this.reduceActions[63] = function(rhs) { + rhs[1].absolute = true; + rhs[1].steps.unshift(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, [])); + return rhs[1]; + }; + this.reduceActions[64] = function(rhs) { + rhs[0].steps.push(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, [])); + rhs[0].steps.push(rhs[2]); + return rhs[0]; + }; + this.reduceActions[65] = function(rhs) { + return new Step(Step.SELF, NodeTest.nodeTest, []); + }; + this.reduceActions[66] = function(rhs) { + return new Step(Step.PARENT, NodeTest.nodeTest, []); + }; + this.reduceActions[67] = function(rhs) { + return new VariableReference(rhs[1]); + }; + this.reduceActions[68] = function(rhs) { + return NodeTest.nameTestAny; + }; + this.reduceActions[69] = function(rhs) { + return new NodeTest.NameTestPrefixAny(rhs[0].split(":")[0]); + }; + this.reduceActions[70] = function(rhs) { + return new NodeTest.NameTestQName(rhs[0]); + }; + }; + XPathParser.actionTable = [ + " s s sssssssss s ss s ss", + " s ", + "r rrrrrrrrr rrrrrrr rr r ", + " rrrrr ", + " s s sssssssss s ss s ss", + "rs rrrrrrrr s sssssrrrrrr rrs rs ", + " s s sssssssss s ss s ss", + " s ", + " s ", + "r rrrrrrrrr rrrrrrr rr rr ", + "r rrrrrrrrr rrrrrrr rr rr ", + "r rrrrrrrrr rrrrrrr rr rr ", + "r rrrrrrrrr rrrrrrr rr rr ", + "r rrrrrrrrr rrrrrrr rr rr ", + " s ", + " s ", + " s s sssss s s ", + "r rrrrrrrrr rrrrrrr rr r ", + "a ", + "r s rr r ", + "r sr rr r ", + "r s rr s rr r ", + "r rssrr rss rr r ", + "r rrrrr rrrss rr r ", + "r rrrrrsss rrrrr rr r ", + "r rrrrrrrr rrrrr rr r ", + "r rrrrrrrr rrrrrs rr r ", + "r rrrrrrrr rrrrrr rr r ", + "r rrrrrrrr rrrrrr rr r ", + "r srrrrrrrr rrrrrrs rr sr ", + "r srrrrrrrr rrrrrrs rr r ", + "r rrrrrrrrr rrrrrrr rr rr ", + "r rrrrrrrrr rrrrrrr rr rr ", + "r rrrrrrrrr rrrrrrr rr rr ", + "r rrrrrrrr rrrrrr rr r ", + "r rrrrrrrr rrrrrr rr r ", + "r rrrrrrrrr rrrrrrr rr r ", + "r rrrrrrrrr rrrrrrr rr r ", + " sssss ", + "r rrrrrrrrr rrrrrrr rr sr ", + "r rrrrrrrrr rrrrrrr rr r ", + "r rrrrrrrrr rrrrrrr rr rr ", + "r rrrrrrrrr rrrrrrr rr rr ", + " s ", + "r srrrrrrrr rrrrrrs rr r ", + "r rrrrrrrr rrrrr rr r ", + " s ", + " s ", + " rrrrr ", + " s s sssssssss s sss s ss", + "r srrrrrrrr rrrrrrs rr r ", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss s ss s ss", + " s s sssssssss ss s ss", + " s s sssssssss s ss s ss", + " s s sssss s s ", + " s s sssss s s ", + "r rrrrrrrrr rrrrrrr rr rr ", + " s s sssss s s ", + " s s sssss s s ", + "r rrrrrrrrr rrrrrrr rr sr ", + "r rrrrrrrrr rrrrrrr rr sr ", + "r rrrrrrrrr rrrrrrr rr r ", + "r rrrrrrrrr rrrrrrr rr rr ", + " s ", + "r rrrrrrrrr rrrrrrr rr rr ", + "r rrrrrrrrr rrrrrrr rr rr ", + " rr ", + " s ", + " rs ", + "r sr rr r ", + "r s rr s rr r ", + "r rssrr rss rr r ", + "r rssrr rss rr r ", + "r rrrrr rrrss rr r ", + "r rrrrr rrrss rr r ", + "r rrrrr rrrss rr r ", + "r rrrrr rrrss rr r ", + "r rrrrrsss rrrrr rr r ", + "r rrrrrsss rrrrr rr r ", + "r rrrrrrrr rrrrr rr r ", + "r rrrrrrrr rrrrr rr r ", + "r rrrrrrrr rrrrr rr r ", + "r rrrrrrrr rrrrrr rr r ", + " r ", + " s ", + "r srrrrrrrr rrrrrrs rr r ", + "r srrrrrrrr rrrrrrs rr r ", + "r rrrrrrrrr rrrrrrr rr r ", + "r rrrrrrrrr rrrrrrr rr r ", + "r rrrrrrrrr rrrrrrr rr r ", + "r rrrrrrrrr rrrrrrr rr r ", + "r rrrrrrrrr rrrrrrr rr rr ", + "r rrrrrrrrr rrrrrrr rr rr ", + " s s sssssssss s ss s ss", + "r rrrrrrrrr rrrrrrr rr rr ", + " r " + ]; + XPathParser.actionTableNumber = [ + ` 1 0 /.-,+*)(' & %$ # "!`, + " J ", + "a aaaaaaaaa aaaaaaa aa a ", + " YYYYY ", + ` 1 0 /.-,+*)(' & %$ # "!`, + `K1 KKKKKKKK . +*)('KKKKKK KK# K" `, + ` 1 0 /.-,+*)(' & %$ # "!`, + " N ", + " O ", + "e eeeeeeeee eeeeeee ee ee ", + "f fffffffff fffffff ff ff ", + "d ddddddddd ddddddd dd dd ", + "B BBBBBBBBB BBBBBBB BB BB ", + "A AAAAAAAAA AAAAAAA AA AA ", + " P ", + " Q ", + ` 1 . +*)(' # " `, + "b bbbbbbbbb bbbbbbb bb b ", + " ", + "! S !! ! ", + '" T" "" " ', + "$ V $$ U $$ $ ", + "& &ZY&& &XW && & ", + ") ))))) )))\\[ )) ) ", + ". ....._^] ..... .. . ", + "1 11111111 11111 11 1 ", + "5 55555555 55555` 55 5 ", + "7 77777777 777777 77 7 ", + "9 99999999 999999 99 9 ", + ": c:::::::: ::::::b :: a: ", + "I fIIIIIIII IIIIIIe II I ", + "= ========= ======= == == ", + "? ????????? ??????? ?? ?? ", + "C CCCCCCCCC CCCCCCC CC CC ", + "J JJJJJJJJ JJJJJJ JJ J ", + "M MMMMMMMM MMMMMM MM M ", + "N NNNNNNNNN NNNNNNN NN N ", + "P PPPPPPPPP PPPPPPP PP P ", + " +*)(' ", + "R RRRRRRRRR RRRRRRR RR aR ", + "U UUUUUUUUU UUUUUUU UU U ", + "Z ZZZZZZZZZ ZZZZZZZ ZZ ZZ ", + "c ccccccccc ccccccc cc cc ", + " j ", + "L fLLLLLLLL LLLLLLe LL L ", + "6 66666666 66666 66 6 ", + " k ", + " l ", + " XXXXX ", + ` 1 0 /.-,+*)(' & %$m # "!`, + "_ f________ ______e __ _ ", + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 0 /.-,+*)(' %$ # "!`, + ` 1 0 /.-,+*)(' & %$ # "!`, + ` 1 . +*)(' # " `, + ` 1 . +*)(' # " `, + "> >>>>>>>>> >>>>>>> >> >> ", + ` 1 . +*)(' # " `, + ` 1 . +*)(' # " `, + "Q QQQQQQQQQ QQQQQQQ QQ aQ ", + "V VVVVVVVVV VVVVVVV VV aV ", + "T TTTTTTTTT TTTTTTT TT T ", + "@ @@@@@@@@@ @@@@@@@ @@ @@ ", + " \x87 ", + "[ [[[[[[[[[ [[[[[[[ [[ [[ ", + "D DDDDDDDDD DDDDDDD DD DD ", + " HH ", + " \x88 ", + " F\x89 ", + "# T# ## # ", + "% V %% U %% % ", + "' 'ZY'' 'XW '' ' ", + "( (ZY(( (XW (( ( ", + "+ +++++ +++\\[ ++ + ", + "* ***** ***\\[ ** * ", + "- ----- ---\\[ -- - ", + ", ,,,,, ,,,\\[ ,, , ", + "0 00000_^] 00000 00 0 ", + "/ /////_^] ///// // / ", + "2 22222222 22222 22 2 ", + "3 33333333 33333 33 3 ", + "4 44444444 44444 44 4 ", + "8 88888888 888888 88 8 ", + " ^ ", + " \x8A ", + "; f;;;;;;;; ;;;;;;e ;; ; ", + "< f<<<<<<<< <<<<<?@ AB CDEFGH IJ ", + " ", + " ", + " ", + "L456789:;<=>?@ AB CDEFGH IJ ", + " M EFGH IJ ", + " N;<=>?@ AB CDEFGH IJ ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " S EFGH IJ ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " e ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " h J ", + " i j ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "o456789:;<=>?@ ABpqCDEFGH IJ ", + " ", + " r6789:;<=>?@ AB CDEFGH IJ ", + " s789:;<=>?@ AB CDEFGH IJ ", + " t89:;<=>?@ AB CDEFGH IJ ", + " u89:;<=>?@ AB CDEFGH IJ ", + " v9:;<=>?@ AB CDEFGH IJ ", + " w9:;<=>?@ AB CDEFGH IJ ", + " x9:;<=>?@ AB CDEFGH IJ ", + " y9:;<=>?@ AB CDEFGH IJ ", + " z:;<=>?@ AB CDEFGH IJ ", + " {:;<=>?@ AB CDEFGH IJ ", + " |;<=>?@ AB CDEFGH IJ ", + " };<=>?@ AB CDEFGH IJ ", + " ~;<=>?@ AB CDEFGH IJ ", + " \x7F=>?@ AB CDEFGH IJ ", + "\x80456789:;<=>?@ AB CDEFGH IJ\x81", + " \x82 EFGH IJ ", + " \x83 EFGH IJ ", + " ", + " \x84 GH IJ ", + " \x85 GH IJ ", + " i \x86 ", + " i \x87 ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "o456789:;<=>?@ AB\x8CqCDEFGH IJ ", + " ", + " " + ]; + XPathParser.productions = [ + [1, 1, 2], + [2, 1, 3], + [3, 1, 4], + [3, 3, 3, -9, 4], + [4, 1, 5], + [4, 3, 4, -8, 5], + [5, 1, 6], + [5, 3, 5, -22, 6], + [5, 3, 5, -5, 6], + [6, 1, 7], + [6, 3, 6, -23, 7], + [6, 3, 6, -24, 7], + [6, 3, 6, -6, 7], + [6, 3, 6, -7, 7], + [7, 1, 8], + [7, 3, 7, -25, 8], + [7, 3, 7, -26, 8], + [8, 1, 9], + [8, 3, 8, -12, 9], + [8, 3, 8, -11, 9], + [8, 3, 8, -10, 9], + [9, 1, 10], + [9, 2, -26, 9], + [10, 1, 11], + [10, 3, 10, -27, 11], + [11, 1, 12], + [11, 1, 13], + [11, 3, 13, -28, 14], + [11, 3, 13, -4, 14], + [13, 1, 15], + [13, 2, 13, 16], + [15, 1, 17], + [15, 3, -29, 2, -30], + [15, 1, -15], + [15, 1, -16], + [15, 1, 18], + [18, 3, -13, -29, -30], + [18, 4, -13, -29, 19, -30], + [19, 1, 20], + [19, 3, 20, -31, 19], + [20, 1, 2], + [12, 1, 14], + [12, 1, 21], + [21, 1, -28], + [21, 2, -28, 14], + [21, 1, 22], + [14, 1, 23], + [14, 3, 14, -28, 23], + [14, 1, 24], + [23, 2, 25, 26], + [23, 1, 26], + [23, 3, 25, 26, 27], + [23, 2, 26, 27], + [23, 1, 28], + [27, 1, 16], + [27, 2, 16, 27], + [25, 2, -14, -3], + [25, 1, -32], + [26, 1, 29], + [26, 3, -20, -29, -30], + [26, 4, -21, -29, -15, -30], + [16, 3, -33, 30, -34], + [30, 1, 2], + [22, 2, -4, 14], + [24, 3, 14, -4, 23], + [28, 1, -35], + [28, 1, -2], + [17, 2, -36, -18], + [29, 1, -17], + [29, 1, -19], + [29, 1, -18] + ]; + XPathParser.DOUBLEDOT = 2; + XPathParser.DOUBLECOLON = 3; + XPathParser.DOUBLESLASH = 4; + XPathParser.NOTEQUAL = 5; + XPathParser.LESSTHANOREQUAL = 6; + XPathParser.GREATERTHANOREQUAL = 7; + XPathParser.AND = 8; + XPathParser.OR = 9; + XPathParser.MOD = 10; + XPathParser.DIV = 11; + XPathParser.MULTIPLYOPERATOR = 12; + XPathParser.FUNCTIONNAME = 13; + XPathParser.AXISNAME = 14; + XPathParser.LITERAL = 15; + XPathParser.NUMBER = 16; + XPathParser.ASTERISKNAMETEST = 17; + XPathParser.QNAME = 18; + XPathParser.NCNAMECOLONASTERISK = 19; + XPathParser.NODETYPE = 20; + XPathParser.PROCESSINGINSTRUCTIONWITHLITERAL = 21; + XPathParser.EQUALS = 22; + XPathParser.LESSTHAN = 23; + XPathParser.GREATERTHAN = 24; + XPathParser.PLUS = 25; + XPathParser.MINUS = 26; + XPathParser.BAR = 27; + XPathParser.SLASH = 28; + XPathParser.LEFTPARENTHESIS = 29; + XPathParser.RIGHTPARENTHESIS = 30; + XPathParser.COMMA = 31; + XPathParser.AT = 32; + XPathParser.LEFTBRACKET = 33; + XPathParser.RIGHTBRACKET = 34; + XPathParser.DOT = 35; + XPathParser.DOLLAR = 36; + XPathParser.prototype.tokenize = function(s1) { + var types = []; + var values = []; + var s = s1 + "\0"; + var pos = 0; + var c = s.charAt(pos++); + while (1) { + while (c == " " || c == " " || c == "\r" || c == "\n") { + c = s.charAt(pos++); + } + if (c == "\0" || pos >= s.length) { + break; + } + if (c == "(") { + types.push(XPathParser.LEFTPARENTHESIS); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == ")") { + types.push(XPathParser.RIGHTPARENTHESIS); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == "[") { + types.push(XPathParser.LEFTBRACKET); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == "]") { + types.push(XPathParser.RIGHTBRACKET); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == "@") { + types.push(XPathParser.AT); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == ",") { + types.push(XPathParser.COMMA); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == "|") { + types.push(XPathParser.BAR); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == "+") { + types.push(XPathParser.PLUS); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == "-") { + types.push(XPathParser.MINUS); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == "=") { + types.push(XPathParser.EQUALS); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == "$") { + types.push(XPathParser.DOLLAR); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == ".") { + c = s.charAt(pos++); + if (c == ".") { + types.push(XPathParser.DOUBLEDOT); + values.push(".."); + c = s.charAt(pos++); + continue; + } + if (c >= "0" && c <= "9") { + var number = "." + c; + c = s.charAt(pos++); + while (c >= "0" && c <= "9") { + number += c; + c = s.charAt(pos++); + } + types.push(XPathParser.NUMBER); + values.push(number); + continue; + } + types.push(XPathParser.DOT); + values.push("."); + continue; + } + if (c == "'" || c == '"') { + var delimiter = c; + var literal = ""; + while (pos < s.length && (c = s.charAt(pos)) !== delimiter) { + literal += c; + pos += 1; + } + if (c !== delimiter) { + throw XPathException.fromMessage("Unterminated string literal: " + delimiter + literal); + } + pos += 1; + types.push(XPathParser.LITERAL); + values.push(literal); + c = s.charAt(pos++); + continue; + } + if (c >= "0" && c <= "9") { + var number = c; + c = s.charAt(pos++); + while (c >= "0" && c <= "9") { + number += c; + c = s.charAt(pos++); + } + if (c == ".") { + if (s.charAt(pos) >= "0" && s.charAt(pos) <= "9") { + number += c; + number += s.charAt(pos++); + c = s.charAt(pos++); + while (c >= "0" && c <= "9") { + number += c; + c = s.charAt(pos++); + } + } + } + types.push(XPathParser.NUMBER); + values.push(number); + continue; + } + if (c == "*") { + if (types.length > 0) { + var last = types[types.length - 1]; + if (last != XPathParser.AT && last != XPathParser.DOUBLECOLON && last != XPathParser.LEFTPARENTHESIS && last != XPathParser.LEFTBRACKET && last != XPathParser.AND && last != XPathParser.OR && last != XPathParser.MOD && last != XPathParser.DIV && last != XPathParser.MULTIPLYOPERATOR && last != XPathParser.SLASH && last != XPathParser.DOUBLESLASH && last != XPathParser.BAR && last != XPathParser.PLUS && last != XPathParser.MINUS && last != XPathParser.EQUALS && last != XPathParser.NOTEQUAL && last != XPathParser.LESSTHAN && last != XPathParser.LESSTHANOREQUAL && last != XPathParser.GREATERTHAN && last != XPathParser.GREATERTHANOREQUAL) { + types.push(XPathParser.MULTIPLYOPERATOR); + values.push(c); + c = s.charAt(pos++); + continue; + } + } + types.push(XPathParser.ASTERISKNAMETEST); + values.push(c); + c = s.charAt(pos++); + continue; + } + if (c == ":") { + if (s.charAt(pos) == ":") { + types.push(XPathParser.DOUBLECOLON); + values.push("::"); + pos++; + c = s.charAt(pos++); + continue; + } + } + if (c == "/") { + c = s.charAt(pos++); + if (c == "/") { + types.push(XPathParser.DOUBLESLASH); + values.push("//"); + c = s.charAt(pos++); + continue; + } + types.push(XPathParser.SLASH); + values.push("/"); + continue; + } + if (c == "!") { + if (s.charAt(pos) == "=") { + types.push(XPathParser.NOTEQUAL); + values.push("!="); + pos++; + c = s.charAt(pos++); + continue; + } + } + if (c == "<") { + if (s.charAt(pos) == "=") { + types.push(XPathParser.LESSTHANOREQUAL); + values.push("<="); + pos++; + c = s.charAt(pos++); + continue; + } + types.push(XPathParser.LESSTHAN); + values.push("<"); + c = s.charAt(pos++); + continue; + } + if (c == ">") { + if (s.charAt(pos) == "=") { + types.push(XPathParser.GREATERTHANOREQUAL); + values.push(">="); + pos++; + c = s.charAt(pos++); + continue; + } + types.push(XPathParser.GREATERTHAN); + values.push(">"); + c = s.charAt(pos++); + continue; + } + if (c == "_" || Utilities.isLetter(c.charCodeAt(0))) { + var name2 = c; + c = s.charAt(pos++); + while (Utilities.isNCNameChar(c.charCodeAt(0))) { + name2 += c; + c = s.charAt(pos++); + } + if (types.length > 0) { + var last = types[types.length - 1]; + if (last != XPathParser.AT && last != XPathParser.DOUBLECOLON && last != XPathParser.LEFTPARENTHESIS && last != XPathParser.LEFTBRACKET && last != XPathParser.AND && last != XPathParser.OR && last != XPathParser.MOD && last != XPathParser.DIV && last != XPathParser.MULTIPLYOPERATOR && last != XPathParser.SLASH && last != XPathParser.DOUBLESLASH && last != XPathParser.BAR && last != XPathParser.PLUS && last != XPathParser.MINUS && last != XPathParser.EQUALS && last != XPathParser.NOTEQUAL && last != XPathParser.LESSTHAN && last != XPathParser.LESSTHANOREQUAL && last != XPathParser.GREATERTHAN && last != XPathParser.GREATERTHANOREQUAL) { + if (name2 == "and") { + types.push(XPathParser.AND); + values.push(name2); + continue; + } + if (name2 == "or") { + types.push(XPathParser.OR); + values.push(name2); + continue; + } + if (name2 == "mod") { + types.push(XPathParser.MOD); + values.push(name2); + continue; + } + if (name2 == "div") { + types.push(XPathParser.DIV); + values.push(name2); + continue; + } + } + } + if (c == ":") { + if (s.charAt(pos) == "*") { + types.push(XPathParser.NCNAMECOLONASTERISK); + values.push(name2 + ":*"); + pos++; + c = s.charAt(pos++); + continue; + } + if (s.charAt(pos) == "_" || Utilities.isLetter(s.charCodeAt(pos))) { + name2 += ":"; + c = s.charAt(pos++); + while (Utilities.isNCNameChar(c.charCodeAt(0))) { + name2 += c; + c = s.charAt(pos++); + } + if (c == "(") { + types.push(XPathParser.FUNCTIONNAME); + values.push(name2); + continue; + } + types.push(XPathParser.QNAME); + values.push(name2); + continue; + } + if (s.charAt(pos) == ":") { + types.push(XPathParser.AXISNAME); + values.push(name2); + continue; + } + } + if (c == "(") { + if (name2 == "comment" || name2 == "text" || name2 == "node") { + types.push(XPathParser.NODETYPE); + values.push(name2); + continue; + } + if (name2 == "processing-instruction") { + if (s.charAt(pos) == ")") { + types.push(XPathParser.NODETYPE); + } else { + types.push(XPathParser.PROCESSINGINSTRUCTIONWITHLITERAL); + } + values.push(name2); + continue; + } + types.push(XPathParser.FUNCTIONNAME); + values.push(name2); + continue; + } + types.push(XPathParser.QNAME); + values.push(name2); + continue; + } + throw new Error("Unexpected character " + c); + } + types.push(1); + values.push("[EOF]"); + return [types, values]; + }; + XPathParser.SHIFT = "s"; + XPathParser.REDUCE = "r"; + XPathParser.ACCEPT = "a"; + XPathParser.prototype.parse = function(s) { + if (!s) { + throw new Error("XPath expression unspecified."); + } + if (typeof s !== "string") { + throw new Error("XPath expression must be a string."); + } + var types; + var values; + var res = this.tokenize(s); + if (res == void 0) { + return void 0; + } + types = res[0]; + values = res[1]; + var tokenPos = 0; + var state = []; + var tokenType = []; + var tokenValue = []; + var s; + var a; + var t; + state.push(0); + tokenType.push(1); + tokenValue.push("_S"); + a = types[tokenPos]; + t = values[tokenPos++]; + while (1) { + s = state[state.length - 1]; + switch (XPathParser.actionTable[s].charAt(a - 1)) { + case XPathParser.SHIFT: + tokenType.push(-a); + tokenValue.push(t); + state.push(XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32); + a = types[tokenPos]; + t = values[tokenPos++]; + break; + case XPathParser.REDUCE: + var num = XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][1]; + var rhs = []; + for (var i = 0; i < num; i++) { + tokenType.pop(); + rhs.unshift(tokenValue.pop()); + state.pop(); + } + var s_ = state[state.length - 1]; + tokenType.push(XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][0]); + if (this.reduceActions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32] == void 0) { + tokenValue.push(rhs[0]); + } else { + tokenValue.push(this.reduceActions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32](rhs)); + } + state.push(XPathParser.gotoTable[s_].charCodeAt(XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][0] - 2) - 33); + break; + case XPathParser.ACCEPT: + return new XPath(tokenValue.pop()); + default: + throw new Error("XPath parse error"); + } + } + }; + XPath.prototype = new Object(); + XPath.prototype.constructor = XPath; + XPath.superclass = Object.prototype; + function XPath(e) { + this.expression = e; + } + XPath.prototype.toString = function() { + return this.expression.toString(); + }; + function setIfUnset(obj, prop, value) { + if (!(prop in obj)) { + obj[prop] = value; + } + } + XPath.prototype.evaluate = function(c) { + var node = c.expressionContextNode; + if (!(isNil(node) || isNodeLike(node))) { + throw new Error("Context node does not appear to be a valid DOM node."); + } + c.contextNode = c.expressionContextNode; + c.contextSize = 1; + c.contextPosition = 1; + if (c.isHtml) { + setIfUnset(c, "caseInsensitive", true); + setIfUnset(c, "allowAnyNamespaceForNoPrefix", true); + } + setIfUnset(c, "caseInsensitive", false); + return this.expression.evaluate(c); + }; + XPath.XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace"; + XPath.XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/"; + Expression.prototype = new Object(); + Expression.prototype.constructor = Expression; + Expression.superclass = Object.prototype; + function Expression() { + } + Expression.prototype.init = function() { + }; + Expression.prototype.toString = function() { + return ""; + }; + Expression.prototype.evaluate = function(c) { + throw new Error("Could not evaluate expression."); + }; + UnaryOperation.prototype = new Expression(); + UnaryOperation.prototype.constructor = UnaryOperation; + UnaryOperation.superclass = Expression.prototype; + function UnaryOperation(rhs) { + if (arguments.length > 0) { + this.init(rhs); + } + } + UnaryOperation.prototype.init = function(rhs) { + this.rhs = rhs; + }; + UnaryMinusOperation.prototype = new UnaryOperation(); + UnaryMinusOperation.prototype.constructor = UnaryMinusOperation; + UnaryMinusOperation.superclass = UnaryOperation.prototype; + function UnaryMinusOperation(rhs) { + if (arguments.length > 0) { + this.init(rhs); + } + } + UnaryMinusOperation.prototype.init = function(rhs) { + UnaryMinusOperation.superclass.init.call(this, rhs); + }; + UnaryMinusOperation.prototype.evaluate = function(c) { + return this.rhs.evaluate(c).number().negate(); + }; + UnaryMinusOperation.prototype.toString = function() { + return "-" + this.rhs.toString(); + }; + BinaryOperation.prototype = new Expression(); + BinaryOperation.prototype.constructor = BinaryOperation; + BinaryOperation.superclass = Expression.prototype; + function BinaryOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + BinaryOperation.prototype.init = function(lhs, rhs) { + this.lhs = lhs; + this.rhs = rhs; + }; + OrOperation.prototype = new BinaryOperation(); + OrOperation.prototype.constructor = OrOperation; + OrOperation.superclass = BinaryOperation.prototype; + function OrOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + OrOperation.prototype.init = function(lhs, rhs) { + OrOperation.superclass.init.call(this, lhs, rhs); + }; + OrOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " or " + this.rhs.toString() + ")"; + }; + OrOperation.prototype.evaluate = function(c) { + var b = this.lhs.evaluate(c).bool(); + if (b.booleanValue()) { + return b; + } + return this.rhs.evaluate(c).bool(); + }; + AndOperation.prototype = new BinaryOperation(); + AndOperation.prototype.constructor = AndOperation; + AndOperation.superclass = BinaryOperation.prototype; + function AndOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + AndOperation.prototype.init = function(lhs, rhs) { + AndOperation.superclass.init.call(this, lhs, rhs); + }; + AndOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " and " + this.rhs.toString() + ")"; + }; + AndOperation.prototype.evaluate = function(c) { + var b = this.lhs.evaluate(c).bool(); + if (!b.booleanValue()) { + return b; + } + return this.rhs.evaluate(c).bool(); + }; + EqualsOperation.prototype = new BinaryOperation(); + EqualsOperation.prototype.constructor = EqualsOperation; + EqualsOperation.superclass = BinaryOperation.prototype; + function EqualsOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + EqualsOperation.prototype.init = function(lhs, rhs) { + EqualsOperation.superclass.init.call(this, lhs, rhs); + }; + EqualsOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " = " + this.rhs.toString() + ")"; + }; + EqualsOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).equals(this.rhs.evaluate(c)); + }; + NotEqualOperation.prototype = new BinaryOperation(); + NotEqualOperation.prototype.constructor = NotEqualOperation; + NotEqualOperation.superclass = BinaryOperation.prototype; + function NotEqualOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + NotEqualOperation.prototype.init = function(lhs, rhs) { + NotEqualOperation.superclass.init.call(this, lhs, rhs); + }; + NotEqualOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " != " + this.rhs.toString() + ")"; + }; + NotEqualOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).notequal(this.rhs.evaluate(c)); + }; + LessThanOperation.prototype = new BinaryOperation(); + LessThanOperation.prototype.constructor = LessThanOperation; + LessThanOperation.superclass = BinaryOperation.prototype; + function LessThanOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + LessThanOperation.prototype.init = function(lhs, rhs) { + LessThanOperation.superclass.init.call(this, lhs, rhs); + }; + LessThanOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).lessthan(this.rhs.evaluate(c)); + }; + LessThanOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " < " + this.rhs.toString() + ")"; + }; + GreaterThanOperation.prototype = new BinaryOperation(); + GreaterThanOperation.prototype.constructor = GreaterThanOperation; + GreaterThanOperation.superclass = BinaryOperation.prototype; + function GreaterThanOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + GreaterThanOperation.prototype.init = function(lhs, rhs) { + GreaterThanOperation.superclass.init.call(this, lhs, rhs); + }; + GreaterThanOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).greaterthan(this.rhs.evaluate(c)); + }; + GreaterThanOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " > " + this.rhs.toString() + ")"; + }; + LessThanOrEqualOperation.prototype = new BinaryOperation(); + LessThanOrEqualOperation.prototype.constructor = LessThanOrEqualOperation; + LessThanOrEqualOperation.superclass = BinaryOperation.prototype; + function LessThanOrEqualOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + LessThanOrEqualOperation.prototype.init = function(lhs, rhs) { + LessThanOrEqualOperation.superclass.init.call(this, lhs, rhs); + }; + LessThanOrEqualOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).lessthanorequal(this.rhs.evaluate(c)); + }; + LessThanOrEqualOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " <= " + this.rhs.toString() + ")"; + }; + GreaterThanOrEqualOperation.prototype = new BinaryOperation(); + GreaterThanOrEqualOperation.prototype.constructor = GreaterThanOrEqualOperation; + GreaterThanOrEqualOperation.superclass = BinaryOperation.prototype; + function GreaterThanOrEqualOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + GreaterThanOrEqualOperation.prototype.init = function(lhs, rhs) { + GreaterThanOrEqualOperation.superclass.init.call(this, lhs, rhs); + }; + GreaterThanOrEqualOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).greaterthanorequal(this.rhs.evaluate(c)); + }; + GreaterThanOrEqualOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " >= " + this.rhs.toString() + ")"; + }; + PlusOperation.prototype = new BinaryOperation(); + PlusOperation.prototype.constructor = PlusOperation; + PlusOperation.superclass = BinaryOperation.prototype; + function PlusOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + PlusOperation.prototype.init = function(lhs, rhs) { + PlusOperation.superclass.init.call(this, lhs, rhs); + }; + PlusOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).number().plus(this.rhs.evaluate(c).number()); + }; + PlusOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " + " + this.rhs.toString() + ")"; + }; + MinusOperation.prototype = new BinaryOperation(); + MinusOperation.prototype.constructor = MinusOperation; + MinusOperation.superclass = BinaryOperation.prototype; + function MinusOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + MinusOperation.prototype.init = function(lhs, rhs) { + MinusOperation.superclass.init.call(this, lhs, rhs); + }; + MinusOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).number().minus(this.rhs.evaluate(c).number()); + }; + MinusOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " - " + this.rhs.toString() + ")"; + }; + MultiplyOperation.prototype = new BinaryOperation(); + MultiplyOperation.prototype.constructor = MultiplyOperation; + MultiplyOperation.superclass = BinaryOperation.prototype; + function MultiplyOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + MultiplyOperation.prototype.init = function(lhs, rhs) { + MultiplyOperation.superclass.init.call(this, lhs, rhs); + }; + MultiplyOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).number().multiply(this.rhs.evaluate(c).number()); + }; + MultiplyOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " * " + this.rhs.toString() + ")"; + }; + DivOperation.prototype = new BinaryOperation(); + DivOperation.prototype.constructor = DivOperation; + DivOperation.superclass = BinaryOperation.prototype; + function DivOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + DivOperation.prototype.init = function(lhs, rhs) { + DivOperation.superclass.init.call(this, lhs, rhs); + }; + DivOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).number().div(this.rhs.evaluate(c).number()); + }; + DivOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " div " + this.rhs.toString() + ")"; + }; + ModOperation.prototype = new BinaryOperation(); + ModOperation.prototype.constructor = ModOperation; + ModOperation.superclass = BinaryOperation.prototype; + function ModOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + ModOperation.prototype.init = function(lhs, rhs) { + ModOperation.superclass.init.call(this, lhs, rhs); + }; + ModOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).number().mod(this.rhs.evaluate(c).number()); + }; + ModOperation.prototype.toString = function() { + return "(" + this.lhs.toString() + " mod " + this.rhs.toString() + ")"; + }; + BarOperation.prototype = new BinaryOperation(); + BarOperation.prototype.constructor = BarOperation; + BarOperation.superclass = BinaryOperation.prototype; + function BarOperation(lhs, rhs) { + if (arguments.length > 0) { + this.init(lhs, rhs); + } + } + BarOperation.prototype.init = function(lhs, rhs) { + BarOperation.superclass.init.call(this, lhs, rhs); + }; + BarOperation.prototype.evaluate = function(c) { + return this.lhs.evaluate(c).nodeset().union(this.rhs.evaluate(c).nodeset()); + }; + BarOperation.prototype.toString = function() { + return map(toString, [this.lhs, this.rhs]).join(" | "); + }; + PathExpr.prototype = new Expression(); + PathExpr.prototype.constructor = PathExpr; + PathExpr.superclass = Expression.prototype; + function PathExpr(filter2, filterPreds, locpath) { + if (arguments.length > 0) { + this.init(filter2, filterPreds, locpath); + } + } + PathExpr.prototype.init = function(filter2, filterPreds, locpath) { + PathExpr.superclass.init.call(this); + this.filter = filter2; + this.filterPredicates = filterPreds; + this.locationPath = locpath; + }; + function findRoot(node) { + while (node && node.parentNode) { + node = node.parentNode; + } + return node; + } + var applyPredicates = function(predicates, c, nodes, reverse) { + if (predicates.length === 0) { + return nodes; + } + var ctx = c.extend({}); + return reduce( + function(inNodes, pred) { + ctx.contextSize = inNodes.length; + return filter( + function(node, i) { + ctx.contextNode = node; + ctx.contextPosition = i + 1; + return PathExpr.predicateMatches(pred, ctx); + }, + inNodes + ); + }, + sortNodes(nodes, reverse), + predicates + ); + }; + PathExpr.getRoot = function(xpc, nodes) { + var firstNode = nodes[0]; + if (firstNode && firstNode.nodeType === NodeTypes.DOCUMENT_NODE) { + return firstNode; + } + if (xpc.virtualRoot) { + return xpc.virtualRoot; + } + if (!firstNode) { + throw new Error("Context node not found when determining document root."); + } + var ownerDoc = firstNode.ownerDocument; + if (ownerDoc) { + return ownerDoc; + } + var n = firstNode; + while (n.parentNode != null) { + n = n.parentNode; + } + return n; + }; + var getPrefixForNamespaceNode = function(attrNode) { + var nm = String(attrNode.name); + if (nm === "xmlns") { + return ""; + } + if (nm.substring(0, 6) === "xmlns:") { + return nm.substring(6, nm.length); + } + return null; + }; + PathExpr.applyStep = function(step, xpc, node) { + if (!node) { + throw new Error("Context node not found when evaluating XPath step: " + step); + } + var newNodes = []; + xpc.contextNode = node; + switch (step.axis) { + case Step.ANCESTOR: + if (xpc.contextNode === xpc.virtualRoot) { + break; + } + var m; + if (xpc.contextNode.nodeType == NodeTypes.ATTRIBUTE_NODE) { + m = PathExpr.getOwnerElement(xpc.contextNode); + } else { + m = xpc.contextNode.parentNode; + } + while (m != null) { + if (step.nodeTest.matches(m, xpc)) { + newNodes.push(m); + } + if (m === xpc.virtualRoot) { + break; + } + m = m.parentNode; + } + break; + case Step.ANCESTORORSELF: + for (var m = xpc.contextNode; m != null; m = m.nodeType == NodeTypes.ATTRIBUTE_NODE ? PathExpr.getOwnerElement(m) : m.parentNode) { + if (step.nodeTest.matches(m, xpc)) { + newNodes.push(m); + } + if (m === xpc.virtualRoot) { + break; + } + } + break; + case Step.ATTRIBUTE: + var nnm = xpc.contextNode.attributes; + if (nnm != null) { + for (var k = 0; k < nnm.length; k++) { + var m = nnm.item(k); + if (step.nodeTest.matches(m, xpc)) { + newNodes.push(m); + } + } + } + break; + case Step.CHILD: + for (var m = xpc.contextNode.firstChild; m != null; m = m.nextSibling) { + if (step.nodeTest.matches(m, xpc)) { + newNodes.push(m); + } + } + break; + case Step.DESCENDANT: + var st = [xpc.contextNode.firstChild]; + while (st.length > 0) { + for (var m = st.pop(); m != null; ) { + if (step.nodeTest.matches(m, xpc)) { + newNodes.push(m); + } + if (m.firstChild != null) { + st.push(m.nextSibling); + m = m.firstChild; + } else { + m = m.nextSibling; + } + } + } + break; + case Step.DESCENDANTORSELF: + if (step.nodeTest.matches(xpc.contextNode, xpc)) { + newNodes.push(xpc.contextNode); + } + var st = [xpc.contextNode.firstChild]; + while (st.length > 0) { + for (var m = st.pop(); m != null; ) { + if (step.nodeTest.matches(m, xpc)) { + newNodes.push(m); + } + if (m.firstChild != null) { + st.push(m.nextSibling); + m = m.firstChild; + } else { + m = m.nextSibling; + } + } + } + break; + case Step.FOLLOWING: + if (xpc.contextNode === xpc.virtualRoot) { + break; + } + var st = []; + if (xpc.contextNode.firstChild != null) { + st.unshift(xpc.contextNode.firstChild); + } else { + st.unshift(xpc.contextNode.nextSibling); + } + for (var m = xpc.contextNode.parentNode; m != null && m.nodeType != NodeTypes.DOCUMENT_NODE && m !== xpc.virtualRoot; m = m.parentNode) { + st.unshift(m.nextSibling); + } + do { + for (var m = st.pop(); m != null; ) { + if (step.nodeTest.matches(m, xpc)) { + newNodes.push(m); + } + if (m.firstChild != null) { + st.push(m.nextSibling); + m = m.firstChild; + } else { + m = m.nextSibling; + } + } + } while (st.length > 0); + break; + case Step.FOLLOWINGSIBLING: + if (xpc.contextNode === xpc.virtualRoot) { + break; + } + for (var m = xpc.contextNode.nextSibling; m != null; m = m.nextSibling) { + if (step.nodeTest.matches(m, xpc)) { + newNodes.push(m); + } + } + break; + case Step.NAMESPACE: + var nodes = {}; + if (xpc.contextNode.nodeType == NodeTypes.ELEMENT_NODE) { + nodes["xml"] = new XPathNamespace("xml", null, XPath.XML_NAMESPACE_URI, xpc.contextNode); + for (var m = xpc.contextNode; m != null && m.nodeType == NodeTypes.ELEMENT_NODE; m = m.parentNode) { + for (var k = 0; k < m.attributes.length; k++) { + var attr = m.attributes.item(k); + var pre = getPrefixForNamespaceNode(attr); + if (pre != null && nodes[pre] == void 0) { + nodes[pre] = new XPathNamespace(pre, attr, attr.value, xpc.contextNode); + } + } + } + for (var pre in nodes) { + var node = nodes[pre]; + if (step.nodeTest.matches(node, xpc)) { + newNodes.push(node); + } + } + } + break; + case Step.PARENT: + m = null; + if (xpc.contextNode !== xpc.virtualRoot) { + if (xpc.contextNode.nodeType == NodeTypes.ATTRIBUTE_NODE) { + m = PathExpr.getOwnerElement(xpc.contextNode); + } else { + m = xpc.contextNode.parentNode; + } + } + if (m != null && step.nodeTest.matches(m, xpc)) { + newNodes.push(m); + } + break; + case Step.PRECEDING: + var st; + if (xpc.virtualRoot != null) { + st = [xpc.virtualRoot]; + } else { + st = [findRoot(xpc.contextNode)]; + } + outer: while (st.length > 0) { + for (var m = st.pop(); m != null; ) { + if (m == xpc.contextNode) { + break outer; + } + if (step.nodeTest.matches(m, xpc)) { + newNodes.unshift(m); + } + if (m.firstChild != null) { + st.push(m.nextSibling); + m = m.firstChild; + } else { + m = m.nextSibling; + } + } + } + break; + case Step.PRECEDINGSIBLING: + if (xpc.contextNode === xpc.virtualRoot) { + break; + } + for (var m = xpc.contextNode.previousSibling; m != null; m = m.previousSibling) { + if (step.nodeTest.matches(m, xpc)) { + newNodes.push(m); + } + } + break; + case Step.SELF: + if (step.nodeTest.matches(xpc.contextNode, xpc)) { + newNodes.push(xpc.contextNode); + } + break; + default: + } + return newNodes; + }; + function applyStepWithPredicates(step, xpc, node) { + return applyPredicates( + step.predicates, + xpc, + PathExpr.applyStep(step, xpc, node), + includes(REVERSE_AXES, step.axis) + ); + } + function applyStepToNodes(context, nodes, step) { + return flatten( + map( + applyStepWithPredicates.bind(null, step, context), + nodes + ) + ); + } + PathExpr.applySteps = function(steps, xpc, nodes) { + return reduce( + applyStepToNodes.bind(null, xpc), + nodes, + steps + ); + }; + PathExpr.prototype.applyFilter = function(c, xpc) { + if (!this.filter) { + return { nodes: [c.contextNode] }; + } + var ns = this.filter.evaluate(c); + if (!Utilities.instance_of(ns, XNodeSet)) { + if (this.filterPredicates != null && this.filterPredicates.length > 0 || this.locationPath != null) { + throw new Error("Path expression filter must evaluate to a nodeset if predicates or location path are used"); + } + return { nonNodes: ns }; + } + return { + nodes: applyPredicates( + this.filterPredicates || [], + xpc, + ns.toUnsortedArray(), + false + // reverse + ) + }; + }; + PathExpr.applyLocationPath = function(locationPath, xpc, nodes) { + if (!locationPath) { + return nodes; + } + var startNodes = locationPath.absolute ? [PathExpr.getRoot(xpc, nodes)] : nodes; + return PathExpr.applySteps(locationPath.steps, xpc, startNodes); + }; + PathExpr.prototype.evaluate = function(c) { + var xpc = assign(new XPathContext(), c); + var filterResult = this.applyFilter(c, xpc); + if ("nonNodes" in filterResult) { + return filterResult.nonNodes; + } + var ns = new XNodeSet(); + ns.addArray(PathExpr.applyLocationPath(this.locationPath, xpc, filterResult.nodes)); + return ns; + }; + PathExpr.predicateMatches = function(pred, c) { + var res = pred.evaluate(c); + return Utilities.instance_of(res, XNumber) ? c.contextPosition === res.numberValue() : res.booleanValue(); + }; + PathExpr.predicateString = function(predicate) { + return wrap("[", "]", predicate.toString()); + }; + PathExpr.predicatesString = function(predicates) { + return join( + "", + map(PathExpr.predicateString, predicates) + ); + }; + PathExpr.prototype.toString = function() { + if (this.filter != void 0) { + var filterStr = toString(this.filter); + if (Utilities.instance_of(this.filter, XString)) { + return wrap("'", "'", filterStr); + } + if (this.filterPredicates != void 0 && this.filterPredicates.length) { + return wrap("(", ")", filterStr) + PathExpr.predicatesString(this.filterPredicates); + } + if (this.locationPath != void 0) { + return filterStr + (this.locationPath.absolute ? "" : "/") + toString(this.locationPath); + } + return filterStr; + } + return toString(this.locationPath); + }; + PathExpr.getOwnerElement = function(n) { + if (n.ownerElement) { + return n.ownerElement; + } + try { + if (n.selectSingleNode) { + return n.selectSingleNode(".."); + } + } catch (e) { + } + var doc = n.nodeType == NodeTypes.DOCUMENT_NODE ? n : n.ownerDocument; + var elts = doc.getElementsByTagName("*"); + for (var i = 0; i < elts.length; i++) { + var elt = elts.item(i); + var nnm = elt.attributes; + for (var j = 0; j < nnm.length; j++) { + var an = nnm.item(j); + if (an === n) { + return elt; + } + } + } + return null; + }; + LocationPath.prototype = new Object(); + LocationPath.prototype.constructor = LocationPath; + LocationPath.superclass = Object.prototype; + function LocationPath(abs, steps) { + if (arguments.length > 0) { + this.init(abs, steps); + } + } + LocationPath.prototype.init = function(abs, steps) { + this.absolute = abs; + this.steps = steps; + }; + LocationPath.prototype.toString = function() { + return (this.absolute ? "/" : "") + map(toString, this.steps).join("/"); + }; + Step.prototype = new Object(); + Step.prototype.constructor = Step; + Step.superclass = Object.prototype; + function Step(axis, nodetest, preds) { + if (arguments.length > 0) { + this.init(axis, nodetest, preds); + } + } + Step.prototype.init = function(axis, nodetest, preds) { + this.axis = axis; + this.nodeTest = nodetest; + this.predicates = preds; + }; + Step.prototype.toString = function() { + return Step.STEPNAMES[this.axis] + "::" + this.nodeTest.toString() + PathExpr.predicatesString(this.predicates); + }; + Step.ANCESTOR = 0; + Step.ANCESTORORSELF = 1; + Step.ATTRIBUTE = 2; + Step.CHILD = 3; + Step.DESCENDANT = 4; + Step.DESCENDANTORSELF = 5; + Step.FOLLOWING = 6; + Step.FOLLOWINGSIBLING = 7; + Step.NAMESPACE = 8; + Step.PARENT = 9; + Step.PRECEDING = 10; + Step.PRECEDINGSIBLING = 11; + Step.SELF = 12; + Step.STEPNAMES = reduce(function(acc, x) { + return acc[x[0]] = x[1], acc; + }, {}, [ + [Step.ANCESTOR, "ancestor"], + [Step.ANCESTORORSELF, "ancestor-or-self"], + [Step.ATTRIBUTE, "attribute"], + [Step.CHILD, "child"], + [Step.DESCENDANT, "descendant"], + [Step.DESCENDANTORSELF, "descendant-or-self"], + [Step.FOLLOWING, "following"], + [Step.FOLLOWINGSIBLING, "following-sibling"], + [Step.NAMESPACE, "namespace"], + [Step.PARENT, "parent"], + [Step.PRECEDING, "preceding"], + [Step.PRECEDINGSIBLING, "preceding-sibling"], + [Step.SELF, "self"] + ]); + var REVERSE_AXES = [ + Step.ANCESTOR, + Step.ANCESTORORSELF, + Step.PARENT, + Step.PRECEDING, + Step.PRECEDINGSIBLING + ]; + NodeTest.prototype = new Object(); + NodeTest.prototype.constructor = NodeTest; + NodeTest.superclass = Object.prototype; + function NodeTest(type, value) { + if (arguments.length > 0) { + this.init(type, value); + } + } + NodeTest.prototype.init = function(type, value) { + this.type = type; + this.value = value; + }; + NodeTest.prototype.toString = function() { + return ""; + }; + NodeTest.prototype.matches = function(n, xpc) { + console.warn("unknown node test type"); + }; + NodeTest.NAMETESTANY = 0; + NodeTest.NAMETESTPREFIXANY = 1; + NodeTest.NAMETESTQNAME = 2; + NodeTest.COMMENT = 3; + NodeTest.TEXT = 4; + NodeTest.PI = 5; + NodeTest.NODE = 6; + NodeTest.isNodeType = function(types) { + return function(node) { + return includes(types, node.nodeType); + }; + }; + NodeTest.makeNodeTestType = function(type, members, ctor) { + var newType = ctor || function() { + }; + newType.prototype = new NodeTest(type); + newType.prototype.constructor = newType; + assign(newType.prototype, members); + return newType; + }; + NodeTest.makeNodeTypeTest = function(type, nodeTypes, stringVal) { + return new (NodeTest.makeNodeTestType(type, { + matches: NodeTest.isNodeType(nodeTypes), + toString: always(stringVal) + }))(); + }; + NodeTest.hasPrefix = function(node) { + return node.prefix || (node.nodeName || node.tagName).indexOf(":") !== -1; + }; + NodeTest.isElementOrAttribute = NodeTest.isNodeType([1, 2]); + NodeTest.nameSpaceMatches = function(prefix, xpc, n) { + var nNamespace = n.namespaceURI || ""; + if (!prefix) { + return !nNamespace || xpc.allowAnyNamespaceForNoPrefix && !NodeTest.hasPrefix(n); + } + var ns = xpc.namespaceResolver.getNamespace(prefix, xpc.expressionContextNode); + if (ns == null) { + throw new Error("Cannot resolve QName " + prefix); + } + return ns === nNamespace; + }; + NodeTest.localNameMatches = function(localName, xpc, n) { + var nLocalName = n.localName || n.nodeName; + return xpc.caseInsensitive ? localName.toLowerCase() === nLocalName.toLowerCase() : localName === nLocalName; + }; + NodeTest.NameTestPrefixAny = NodeTest.makeNodeTestType( + NodeTest.NAMETESTPREFIXANY, + { + matches: function(n, xpc) { + return NodeTest.isElementOrAttribute(n) && NodeTest.nameSpaceMatches(this.prefix, xpc, n); + }, + toString: function() { + return this.prefix + ":*"; + } + }, + function NameTestPrefixAny(prefix) { + this.prefix = prefix; + } + ); + NodeTest.NameTestQName = NodeTest.makeNodeTestType( + NodeTest.NAMETESTQNAME, + { + matches: function(n, xpc) { + return NodeTest.isNodeType( + [ + NodeTypes.ELEMENT_NODE, + NodeTypes.ATTRIBUTE_NODE, + NodeTypes.NAMESPACE_NODE + ] + )(n) && NodeTest.nameSpaceMatches(this.prefix, xpc, n) && NodeTest.localNameMatches(this.localName, xpc, n); + }, + toString: function() { + return this.name; + } + }, + function NameTestQName(name2) { + var nameParts = name2.split(":"); + this.name = name2; + this.prefix = nameParts.length > 1 ? nameParts[0] : null; + this.localName = nameParts[nameParts.length > 1 ? 1 : 0]; + } + ); + NodeTest.PITest = NodeTest.makeNodeTestType(NodeTest.PI, { + matches: function(n, xpc) { + return NodeTest.isNodeType( + [NodeTypes.PROCESSING_INSTRUCTION_NODE] + )(n) && (n.target || n.nodeName) === this.name; + }, + toString: function() { + return wrap('processing-instruction("', '")', this.name); + } + }, function(name2) { + this.name = name2; + }); + NodeTest.nameTestAny = NodeTest.makeNodeTypeTest( + NodeTest.NAMETESTANY, + [ + NodeTypes.ELEMENT_NODE, + NodeTypes.ATTRIBUTE_NODE, + NodeTypes.NAMESPACE_NODE + ], + "*" + ); + NodeTest.textTest = NodeTest.makeNodeTypeTest( + NodeTest.TEXT, + [ + NodeTypes.TEXT_NODE, + NodeTypes.CDATA_SECTION_NODE + ], + "text()" + ); + NodeTest.commentTest = NodeTest.makeNodeTypeTest( + NodeTest.COMMENT, + [NodeTypes.COMMENT_NODE], + "comment()" + ); + NodeTest.nodeTest = NodeTest.makeNodeTypeTest( + NodeTest.NODE, + [ + NodeTypes.ELEMENT_NODE, + NodeTypes.ATTRIBUTE_NODE, + NodeTypes.TEXT_NODE, + NodeTypes.CDATA_SECTION_NODE, + NodeTypes.PROCESSING_INSTRUCTION_NODE, + NodeTypes.COMMENT_NODE, + NodeTypes.DOCUMENT_NODE + ], + "node()" + ); + NodeTest.anyPiTest = NodeTest.makeNodeTypeTest( + NodeTest.PI, + [NodeTypes.PROCESSING_INSTRUCTION_NODE], + "processing-instruction()" + ); + VariableReference.prototype = new Expression(); + VariableReference.prototype.constructor = VariableReference; + VariableReference.superclass = Expression.prototype; + function VariableReference(v) { + if (arguments.length > 0) { + this.init(v); + } + } + VariableReference.prototype.init = function(v) { + this.variable = v; + }; + VariableReference.prototype.toString = function() { + return "$" + this.variable; + }; + VariableReference.prototype.evaluate = function(c) { + var parts = Utilities.resolveQName(this.variable, c.namespaceResolver, c.contextNode, false); + if (parts[0] == null) { + throw new Error("Cannot resolve QName " + fn); + } + var result = c.variableResolver.getVariable(parts[1], parts[0]); + if (!result) { + throw XPathException.fromMessage("Undeclared variable: " + this.toString()); + } + return result; + }; + FunctionCall.prototype = new Expression(); + FunctionCall.prototype.constructor = FunctionCall; + FunctionCall.superclass = Expression.prototype; + function FunctionCall(fn2, args) { + if (arguments.length > 0) { + this.init(fn2, args); + } + } + FunctionCall.prototype.init = function(fn2, args) { + this.functionName = fn2; + this.arguments = args; + }; + FunctionCall.prototype.toString = function() { + var s = this.functionName + "("; + for (var i = 0; i < this.arguments.length; i++) { + if (i > 0) { + s += ", "; + } + s += this.arguments[i].toString(); + } + return s + ")"; + }; + FunctionCall.prototype.evaluate = function(c) { + var f = FunctionResolver.getFunctionFromContext(this.functionName, c); + if (!f) { + throw new Error("Unknown function " + this.functionName); + } + var a = [c].concat(this.arguments); + return f.apply(c.functionResolver.thisArg, a); + }; + var Operators = new Object(); + Operators.equals = function(l, r) { + return l.equals(r); + }; + Operators.notequal = function(l, r) { + return l.notequal(r); + }; + Operators.lessthan = function(l, r) { + return l.lessthan(r); + }; + Operators.greaterthan = function(l, r) { + return l.greaterthan(r); + }; + Operators.lessthanorequal = function(l, r) { + return l.lessthanorequal(r); + }; + Operators.greaterthanorequal = function(l, r) { + return l.greaterthanorequal(r); + }; + XString.prototype = new Expression(); + XString.prototype.constructor = XString; + XString.superclass = Expression.prototype; + function XString(s) { + if (arguments.length > 0) { + this.init(s); + } + } + XString.prototype.init = function(s) { + this.str = String(s); + }; + XString.prototype.toString = function() { + return this.str; + }; + XString.prototype.evaluate = function(c) { + return this; + }; + XString.prototype.string = function() { + return this; + }; + XString.prototype.number = function() { + return new XNumber(this.str); + }; + XString.prototype.bool = function() { + return new XBoolean(this.str); + }; + XString.prototype.nodeset = function() { + throw new Error("Cannot convert string to nodeset"); + }; + XString.prototype.stringValue = function() { + return this.str; + }; + XString.prototype.numberValue = function() { + return this.number().numberValue(); + }; + XString.prototype.booleanValue = function() { + return this.bool().booleanValue(); + }; + XString.prototype.equals = function(r) { + if (Utilities.instance_of(r, XBoolean)) { + return this.bool().equals(r); + } + if (Utilities.instance_of(r, XNumber)) { + return this.number().equals(r); + } + if (Utilities.instance_of(r, XNodeSet)) { + return r.compareWithString(this, Operators.equals); + } + return new XBoolean(this.str == r.str); + }; + XString.prototype.notequal = function(r) { + if (Utilities.instance_of(r, XBoolean)) { + return this.bool().notequal(r); + } + if (Utilities.instance_of(r, XNumber)) { + return this.number().notequal(r); + } + if (Utilities.instance_of(r, XNodeSet)) { + return r.compareWithString(this, Operators.notequal); + } + return new XBoolean(this.str != r.str); + }; + XString.prototype.lessthan = function(r) { + return this.number().lessthan(r); + }; + XString.prototype.greaterthan = function(r) { + return this.number().greaterthan(r); + }; + XString.prototype.lessthanorequal = function(r) { + return this.number().lessthanorequal(r); + }; + XString.prototype.greaterthanorequal = function(r) { + return this.number().greaterthanorequal(r); + }; + XNumber.prototype = new Expression(); + XNumber.prototype.constructor = XNumber; + XNumber.superclass = Expression.prototype; + function XNumber(n) { + if (arguments.length > 0) { + this.init(n); + } + } + XNumber.prototype.init = function(n) { + this.num = typeof n === "string" ? this.parse(n) : Number(n); + }; + XNumber.prototype.numberFormat = /^\s*-?[0-9]*\.?[0-9]+\s*$/; + XNumber.prototype.parse = function(s) { + return this.numberFormat.test(s) ? parseFloat(s) : Number.NaN; + }; + function padSmallNumber(numberStr) { + var parts = numberStr.split("e-"); + var base = parts[0].replace(".", ""); + var exponent = Number(parts[1]); + for (var i = 0; i < exponent - 1; i += 1) { + base = "0" + base; + } + return "0." + base; + } + function padLargeNumber(numberStr) { + var parts = numberStr.split("e"); + var base = parts[0].replace(".", ""); + var exponent = Number(parts[1]); + var zerosToAppend = exponent + 1 - base.length; + for (var i = 0; i < zerosToAppend; i += 1) { + base += "0"; + } + return base; + } + XNumber.prototype.toString = function() { + var strValue = this.num.toString(); + if (strValue.indexOf("e-") !== -1) { + return padSmallNumber(strValue); + } + if (strValue.indexOf("e") !== -1) { + return padLargeNumber(strValue); + } + return strValue; + }; + XNumber.prototype.evaluate = function(c) { + return this; + }; + XNumber.prototype.string = function() { + return new XString(this.toString()); + }; + XNumber.prototype.number = function() { + return this; + }; + XNumber.prototype.bool = function() { + return new XBoolean(this.num); + }; + XNumber.prototype.nodeset = function() { + throw new Error("Cannot convert number to nodeset"); + }; + XNumber.prototype.stringValue = function() { + return this.string().stringValue(); + }; + XNumber.prototype.numberValue = function() { + return this.num; + }; + XNumber.prototype.booleanValue = function() { + return this.bool().booleanValue(); + }; + XNumber.prototype.negate = function() { + return new XNumber(-this.num); + }; + XNumber.prototype.equals = function(r) { + if (Utilities.instance_of(r, XBoolean)) { + return this.bool().equals(r); + } + if (Utilities.instance_of(r, XString)) { + return this.equals(r.number()); + } + if (Utilities.instance_of(r, XNodeSet)) { + return r.compareWithNumber(this, Operators.equals); + } + return new XBoolean(this.num == r.num); + }; + XNumber.prototype.notequal = function(r) { + if (Utilities.instance_of(r, XBoolean)) { + return this.bool().notequal(r); + } + if (Utilities.instance_of(r, XString)) { + return this.notequal(r.number()); + } + if (Utilities.instance_of(r, XNodeSet)) { + return r.compareWithNumber(this, Operators.notequal); + } + return new XBoolean(this.num != r.num); + }; + XNumber.prototype.lessthan = function(r) { + if (Utilities.instance_of(r, XNodeSet)) { + return r.compareWithNumber(this, Operators.greaterthan); + } + if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) { + return this.lessthan(r.number()); + } + return new XBoolean(this.num < r.num); + }; + XNumber.prototype.greaterthan = function(r) { + if (Utilities.instance_of(r, XNodeSet)) { + return r.compareWithNumber(this, Operators.lessthan); + } + if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) { + return this.greaterthan(r.number()); + } + return new XBoolean(this.num > r.num); + }; + XNumber.prototype.lessthanorequal = function(r) { + if (Utilities.instance_of(r, XNodeSet)) { + return r.compareWithNumber(this, Operators.greaterthanorequal); + } + if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) { + return this.lessthanorequal(r.number()); + } + return new XBoolean(this.num <= r.num); + }; + XNumber.prototype.greaterthanorequal = function(r) { + if (Utilities.instance_of(r, XNodeSet)) { + return r.compareWithNumber(this, Operators.lessthanorequal); + } + if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) { + return this.greaterthanorequal(r.number()); + } + return new XBoolean(this.num >= r.num); + }; + XNumber.prototype.plus = function(r) { + return new XNumber(this.num + r.num); + }; + XNumber.prototype.minus = function(r) { + return new XNumber(this.num - r.num); + }; + XNumber.prototype.multiply = function(r) { + return new XNumber(this.num * r.num); + }; + XNumber.prototype.div = function(r) { + return new XNumber(this.num / r.num); + }; + XNumber.prototype.mod = function(r) { + return new XNumber(this.num % r.num); + }; + XBoolean.prototype = new Expression(); + XBoolean.prototype.constructor = XBoolean; + XBoolean.superclass = Expression.prototype; + function XBoolean(b) { + if (arguments.length > 0) { + this.init(b); + } + } + XBoolean.prototype.init = function(b) { + this.b = Boolean(b); + }; + XBoolean.prototype.toString = function() { + return this.b.toString(); + }; + XBoolean.prototype.evaluate = function(c) { + return this; + }; + XBoolean.prototype.string = function() { + return new XString(this.b); + }; + XBoolean.prototype.number = function() { + return new XNumber(this.b); + }; + XBoolean.prototype.bool = function() { + return this; + }; + XBoolean.prototype.nodeset = function() { + throw new Error("Cannot convert boolean to nodeset"); + }; + XBoolean.prototype.stringValue = function() { + return this.string().stringValue(); + }; + XBoolean.prototype.numberValue = function() { + return this.number().numberValue(); + }; + XBoolean.prototype.booleanValue = function() { + return this.b; + }; + XBoolean.prototype.not = function() { + return new XBoolean(!this.b); + }; + XBoolean.prototype.equals = function(r) { + if (Utilities.instance_of(r, XString) || Utilities.instance_of(r, XNumber)) { + return this.equals(r.bool()); + } + if (Utilities.instance_of(r, XNodeSet)) { + return r.compareWithBoolean(this, Operators.equals); + } + return new XBoolean(this.b == r.b); + }; + XBoolean.prototype.notequal = function(r) { + if (Utilities.instance_of(r, XString) || Utilities.instance_of(r, XNumber)) { + return this.notequal(r.bool()); + } + if (Utilities.instance_of(r, XNodeSet)) { + return r.compareWithBoolean(this, Operators.notequal); + } + return new XBoolean(this.b != r.b); + }; + XBoolean.prototype.lessthan = function(r) { + return this.number().lessthan(r); + }; + XBoolean.prototype.greaterthan = function(r) { + return this.number().greaterthan(r); + }; + XBoolean.prototype.lessthanorequal = function(r) { + return this.number().lessthanorequal(r); + }; + XBoolean.prototype.greaterthanorequal = function(r) { + return this.number().greaterthanorequal(r); + }; + XBoolean.true_ = new XBoolean(true); + XBoolean.false_ = new XBoolean(false); + AVLTree.prototype = new Object(); + AVLTree.prototype.constructor = AVLTree; + AVLTree.superclass = Object.prototype; + function AVLTree(n) { + this.init(n); + } + AVLTree.prototype.init = function(n) { + this.left = null; + this.right = null; + this.node = n; + this.depth = 1; + }; + AVLTree.prototype.balance = function() { + var ldepth = this.left == null ? 0 : this.left.depth; + var rdepth = this.right == null ? 0 : this.right.depth; + if (ldepth > rdepth + 1) { + var lldepth = this.left.left == null ? 0 : this.left.left.depth; + var lrdepth = this.left.right == null ? 0 : this.left.right.depth; + if (lldepth < lrdepth) { + this.left.rotateRR(); + } + this.rotateLL(); + } else if (ldepth + 1 < rdepth) { + var rrdepth = this.right.right == null ? 0 : this.right.right.depth; + var rldepth = this.right.left == null ? 0 : this.right.left.depth; + if (rldepth > rrdepth) { + this.right.rotateLL(); + } + this.rotateRR(); + } + }; + AVLTree.prototype.rotateLL = function() { + var nodeBefore = this.node; + var rightBefore = this.right; + this.node = this.left.node; + this.right = this.left; + this.left = this.left.left; + this.right.left = this.right.right; + this.right.right = rightBefore; + this.right.node = nodeBefore; + this.right.updateInNewLocation(); + this.updateInNewLocation(); + }; + AVLTree.prototype.rotateRR = function() { + var nodeBefore = this.node; + var leftBefore = this.left; + this.node = this.right.node; + this.left = this.right; + this.right = this.right.right; + this.left.right = this.left.left; + this.left.left = leftBefore; + this.left.node = nodeBefore; + this.left.updateInNewLocation(); + this.updateInNewLocation(); + }; + AVLTree.prototype.updateInNewLocation = function() { + this.getDepthFromChildren(); + }; + AVLTree.prototype.getDepthFromChildren = function() { + this.depth = this.node == null ? 0 : 1; + if (this.left != null) { + this.depth = this.left.depth + 1; + } + if (this.right != null && this.depth <= this.right.depth) { + this.depth = this.right.depth + 1; + } + }; + function nodeOrder(n1, n2) { + if (n1 === n2) { + return 0; + } + if (n1.compareDocumentPosition) { + var cpos = n1.compareDocumentPosition(n2); + if (cpos & 1) { + return 1; + } + if (cpos & 10) { + return 1; + } + if (cpos & 20) { + return -1; + } + return 0; + } + var d1 = 0, d2 = 0; + for (var m1 = n1; m1 != null; m1 = m1.parentNode || m1.ownerElement) { + d1++; + } + for (var m2 = n2; m2 != null; m2 = m2.parentNode || m2.ownerElement) { + d2++; + } + if (d1 > d2) { + while (d1 > d2) { + n1 = n1.parentNode || n1.ownerElement; + d1--; + } + if (n1 === n2) { + return 1; + } + } else if (d2 > d1) { + while (d2 > d1) { + n2 = n2.parentNode || n2.ownerElement; + d2--; + } + if (n1 === n2) { + return -1; + } + } + var n1Par = n1.parentNode || n1.ownerElement, n2Par = n2.parentNode || n2.ownerElement; + while (n1Par !== n2Par) { + n1 = n1Par; + n2 = n2Par; + n1Par = n1.parentNode || n1.ownerElement; + n2Par = n2.parentNode || n2.ownerElement; + } + var n1isAttr = isAttributeLike(n1); + var n2isAttr = isAttributeLike(n2); + if (n1isAttr && !n2isAttr) { + return -1; + } + if (!n1isAttr && n2isAttr) { + return 1; + } + if (n1.isXPathNamespace) { + if (n1.nodeValue === XPath.XML_NAMESPACE_URI) { + return -1; + } + if (!n2.isXPathNamespace) { + return -1; + } + if (n2.nodeValue === XPath.XML_NAMESPACE_URI) { + return 1; + } + } else if (n2.isXPathNamespace) { + return 1; + } + if (n1Par) { + var cn = n1isAttr ? n1Par.attributes : n1Par.childNodes; + var len = cn.length; + var n1Compare = n1.baseNode || n1; + var n2Compare = n2.baseNode || n2; + for (var i = 0; i < len; i += 1) { + var n = cn[i]; + if (n === n1Compare) { + return -1; + } + if (n === n2Compare) { + return 1; + } + } + } + throw new Error("Unexpected: could not determine node order"); + } + AVLTree.prototype.add = function(n) { + if (n === this.node) { + return false; + } + var o = nodeOrder(n, this.node); + var ret = false; + if (o == -1) { + if (this.left == null) { + this.left = new AVLTree(n); + ret = true; + } else { + ret = this.left.add(n); + if (ret) { + this.balance(); + } + } + } else if (o == 1) { + if (this.right == null) { + this.right = new AVLTree(n); + ret = true; + } else { + ret = this.right.add(n); + if (ret) { + this.balance(); + } + } + } + if (ret) { + this.getDepthFromChildren(); + } + return ret; + }; + XNodeSet.prototype = new Expression(); + XNodeSet.prototype.constructor = XNodeSet; + XNodeSet.superclass = Expression.prototype; + function XNodeSet() { + this.init(); + } + XNodeSet.prototype.init = function() { + this.tree = null; + this.nodes = []; + this.size = 0; + }; + XNodeSet.prototype.toString = function() { + var p = this.first(); + if (p == null) { + return ""; + } + return this.stringForNode(p); + }; + XNodeSet.prototype.evaluate = function(c) { + return this; + }; + XNodeSet.prototype.string = function() { + return new XString(this.toString()); + }; + XNodeSet.prototype.stringValue = function() { + return this.toString(); + }; + XNodeSet.prototype.number = function() { + return new XNumber(this.string()); + }; + XNodeSet.prototype.numberValue = function() { + return Number(this.string()); + }; + XNodeSet.prototype.bool = function() { + return new XBoolean(this.booleanValue()); + }; + XNodeSet.prototype.booleanValue = function() { + return !!this.size; + }; + XNodeSet.prototype.nodeset = function() { + return this; + }; + XNodeSet.prototype.stringForNode = function(n) { + if (n.nodeType == NodeTypes.DOCUMENT_NODE || n.nodeType == NodeTypes.ELEMENT_NODE || n.nodeType === NodeTypes.DOCUMENT_FRAGMENT_NODE) { + return this.stringForContainerNode(n); + } + if (n.nodeType === NodeTypes.ATTRIBUTE_NODE) { + return n.value || n.nodeValue; + } + if (n.isNamespaceNode) { + return n.namespace; + } + return n.nodeValue; + }; + XNodeSet.prototype.stringForContainerNode = function(n) { + var s = ""; + for (var n2 = n.firstChild; n2 != null; n2 = n2.nextSibling) { + var nt = n2.nodeType; + if (nt === 1 || nt === 3 || nt === 4 || nt === 9 || nt === 11) { + s += this.stringForNode(n2); + } + } + return s; + }; + XNodeSet.prototype.buildTree = function() { + if (!this.tree && this.nodes.length) { + this.tree = new AVLTree(this.nodes[0]); + for (var i = 1; i < this.nodes.length; i += 1) { + this.tree.add(this.nodes[i]); + } + } + return this.tree; + }; + XNodeSet.prototype.first = function() { + var p = this.buildTree(); + if (p == null) { + return null; + } + while (p.left != null) { + p = p.left; + } + return p.node; + }; + XNodeSet.prototype.add = function(n) { + for (var i = 0; i < this.nodes.length; i += 1) { + if (n === this.nodes[i]) { + return; + } + } + this.tree = null; + this.nodes.push(n); + this.size += 1; + }; + XNodeSet.prototype.addArray = function(ns) { + var self = this; + forEach(function(x) { + self.add(x); + }, ns); + }; + XNodeSet.prototype.toArray = function() { + var a = []; + this.toArrayRec(this.buildTree(), a); + return a; + }; + XNodeSet.prototype.toArrayRec = function(t, a) { + if (t != null) { + this.toArrayRec(t.left, a); + a.push(t.node); + this.toArrayRec(t.right, a); + } + }; + XNodeSet.prototype.toUnsortedArray = function() { + return this.nodes.slice(); + }; + XNodeSet.prototype.compareWithString = function(r, o) { + var a = this.toUnsortedArray(); + for (var i = 0; i < a.length; i++) { + var n = a[i]; + var l = new XString(this.stringForNode(n)); + var res = o(l, r); + if (res.booleanValue()) { + return res; + } + } + return new XBoolean(false); + }; + XNodeSet.prototype.compareWithNumber = function(r, o) { + var a = this.toUnsortedArray(); + for (var i = 0; i < a.length; i++) { + var n = a[i]; + var l = new XNumber(this.stringForNode(n)); + var res = o(l, r); + if (res.booleanValue()) { + return res; + } + } + return new XBoolean(false); + }; + XNodeSet.prototype.compareWithBoolean = function(r, o) { + return o(this.bool(), r); + }; + XNodeSet.prototype.compareWithNodeSet = function(r, o) { + var arr = this.toUnsortedArray(); + var oInvert = function(lop, rop) { + return o(rop, lop); + }; + for (var i = 0; i < arr.length; i++) { + var l = new XString(this.stringForNode(arr[i])); + var res = r.compareWithString(l, oInvert); + if (res.booleanValue()) { + return res; + } + } + return new XBoolean(false); + }; + XNodeSet.compareWith = curry(function(o, r) { + if (Utilities.instance_of(r, XString)) { + return this.compareWithString(r, o); + } + if (Utilities.instance_of(r, XNumber)) { + return this.compareWithNumber(r, o); + } + if (Utilities.instance_of(r, XBoolean)) { + return this.compareWithBoolean(r, o); + } + return this.compareWithNodeSet(r, o); + }); + XNodeSet.prototype.equals = XNodeSet.compareWith(Operators.equals); + XNodeSet.prototype.notequal = XNodeSet.compareWith(Operators.notequal); + XNodeSet.prototype.lessthan = XNodeSet.compareWith(Operators.lessthan); + XNodeSet.prototype.greaterthan = XNodeSet.compareWith(Operators.greaterthan); + XNodeSet.prototype.lessthanorequal = XNodeSet.compareWith(Operators.lessthanorequal); + XNodeSet.prototype.greaterthanorequal = XNodeSet.compareWith(Operators.greaterthanorequal); + XNodeSet.prototype.union = function(r) { + var ns = new XNodeSet(); + ns.addArray(this.toUnsortedArray()); + ns.addArray(r.toUnsortedArray()); + return ns; + }; + XPathNamespace.prototype = new Object(); + XPathNamespace.prototype.constructor = XPathNamespace; + XPathNamespace.superclass = Object.prototype; + function XPathNamespace(pre, node, uri, p) { + this.isXPathNamespace = true; + this.baseNode = node; + this.ownerDocument = p.ownerDocument; + this.nodeName = pre; + this.prefix = pre; + this.localName = pre; + this.namespaceURI = null; + this.nodeValue = uri; + this.ownerElement = p; + this.nodeType = NodeTypes.NAMESPACE_NODE; + } + XPathNamespace.prototype.toString = function() { + return '{ "' + this.prefix + '", "' + this.namespaceURI + '" }'; + }; + XPathContext.prototype = new Object(); + XPathContext.prototype.constructor = XPathContext; + XPathContext.superclass = Object.prototype; + function XPathContext(vr, nr, fr) { + this.variableResolver = vr != null ? vr : new VariableResolver(); + this.namespaceResolver = nr != null ? nr : new NamespaceResolver(); + this.functionResolver = fr != null ? fr : new FunctionResolver(); + } + XPathContext.prototype.extend = function(newProps) { + return assign(new XPathContext(), this, newProps); + }; + VariableResolver.prototype = new Object(); + VariableResolver.prototype.constructor = VariableResolver; + VariableResolver.superclass = Object.prototype; + function VariableResolver() { + } + VariableResolver.prototype.getVariable = function(ln, ns) { + return null; + }; + FunctionResolver.prototype = new Object(); + FunctionResolver.prototype.constructor = FunctionResolver; + FunctionResolver.superclass = Object.prototype; + function FunctionResolver(thisArg) { + this.thisArg = thisArg != null ? thisArg : Functions; + this.functions = new Object(); + this.addStandardFunctions(); + } + FunctionResolver.prototype.addStandardFunctions = function() { + this.functions["{}last"] = Functions.last; + this.functions["{}position"] = Functions.position; + this.functions["{}count"] = Functions.count; + this.functions["{}id"] = Functions.id; + this.functions["{}local-name"] = Functions.localName; + this.functions["{}namespace-uri"] = Functions.namespaceURI; + this.functions["{}name"] = Functions.name; + this.functions["{}string"] = Functions.string; + this.functions["{}concat"] = Functions.concat; + this.functions["{}starts-with"] = Functions.startsWith; + this.functions["{}contains"] = Functions.contains; + this.functions["{}substring-before"] = Functions.substringBefore; + this.functions["{}substring-after"] = Functions.substringAfter; + this.functions["{}substring"] = Functions.substring; + this.functions["{}string-length"] = Functions.stringLength; + this.functions["{}normalize-space"] = Functions.normalizeSpace; + this.functions["{}translate"] = Functions.translate; + this.functions["{}boolean"] = Functions.boolean_; + this.functions["{}not"] = Functions.not; + this.functions["{}true"] = Functions.true_; + this.functions["{}false"] = Functions.false_; + this.functions["{}lang"] = Functions.lang; + this.functions["{}number"] = Functions.number; + this.functions["{}sum"] = Functions.sum; + this.functions["{}floor"] = Functions.floor; + this.functions["{}ceiling"] = Functions.ceiling; + this.functions["{}round"] = Functions.round; + }; + FunctionResolver.prototype.addFunction = function(ns, ln, f) { + this.functions["{" + ns + "}" + ln] = f; + }; + FunctionResolver.getFunctionFromContext = function(qName, context) { + var parts = Utilities.resolveQName(qName, context.namespaceResolver, context.contextNode, false); + if (parts[0] === null) { + throw new Error("Cannot resolve QName " + name); + } + return context.functionResolver.getFunction(parts[1], parts[0]); + }; + FunctionResolver.prototype.getFunction = function(localName, namespace) { + return this.functions["{" + namespace + "}" + localName]; + }; + NamespaceResolver.prototype = new Object(); + NamespaceResolver.prototype.constructor = NamespaceResolver; + NamespaceResolver.superclass = Object.prototype; + function NamespaceResolver() { + } + NamespaceResolver.prototype.getNamespace = function(prefix, n) { + if (prefix == "xml") { + return XPath.XML_NAMESPACE_URI; + } else if (prefix == "xmlns") { + return XPath.XMLNS_NAMESPACE_URI; + } + if (n.nodeType == NodeTypes.DOCUMENT_NODE) { + n = n.documentElement; + } else if (n.nodeType == NodeTypes.ATTRIBUTE_NODE) { + n = PathExpr.getOwnerElement(n); + } else if (n.nodeType != NodeTypes.ELEMENT_NODE) { + n = n.parentNode; + } + while (n != null && n.nodeType == NodeTypes.ELEMENT_NODE) { + var nnm = n.attributes; + for (var i = 0; i < nnm.length; i++) { + var a = nnm.item(i); + var aname = a.name || a.nodeName; + if (aname === "xmlns" && prefix === "" || aname === "xmlns:" + prefix) { + return String(a.value || a.nodeValue); + } + } + n = n.parentNode; + } + return null; + }; + var Functions = new Object(); + Functions.last = function(c) { + if (arguments.length != 1) { + throw new Error("Function last expects ()"); + } + return new XNumber(c.contextSize); + }; + Functions.position = function(c) { + if (arguments.length != 1) { + throw new Error("Function position expects ()"); + } + return new XNumber(c.contextPosition); + }; + Functions.count = function() { + var c = arguments[0]; + var ns; + if (arguments.length != 2 || !Utilities.instance_of(ns = arguments[1].evaluate(c), XNodeSet)) { + throw new Error("Function count expects (node-set)"); + } + return new XNumber(ns.size); + }; + Functions.id = function() { + var c = arguments[0]; + var id; + if (arguments.length != 2) { + throw new Error("Function id expects (object)"); + } + id = arguments[1].evaluate(c); + if (Utilities.instance_of(id, XNodeSet)) { + id = id.toArray().join(" "); + } else { + id = id.stringValue(); + } + var ids = id.split(/[\x0d\x0a\x09\x20]+/); + var count = 0; + var ns = new XNodeSet(); + var doc = c.contextNode.nodeType == NodeTypes.DOCUMENT_NODE ? c.contextNode : c.contextNode.ownerDocument; + for (var i = 0; i < ids.length; i++) { + var n; + if (doc.getElementById) { + n = doc.getElementById(ids[i]); + } else { + n = Utilities.getElementById(doc, ids[i]); + } + if (n != null) { + ns.add(n); + count++; + } + } + return ns; + }; + Functions.localName = function(c, eNode) { + var n; + if (arguments.length == 1) { + n = c.contextNode; + } else if (arguments.length == 2) { + n = eNode.evaluate(c).first(); + } else { + throw new Error("Function local-name expects (node-set?)"); + } + if (n == null) { + return new XString(""); + } + return new XString( + n.localName || // standard elements and attributes + n.baseName || // IE + n.target || // processing instructions + n.nodeName || // DOM1 elements + "" + // fallback + ); + }; + Functions.namespaceURI = function() { + var c = arguments[0]; + var n; + if (arguments.length == 1) { + n = c.contextNode; + } else if (arguments.length == 2) { + n = arguments[1].evaluate(c).first(); + } else { + throw new Error("Function namespace-uri expects (node-set?)"); + } + if (n == null) { + return new XString(""); + } + return new XString(n.namespaceURI || ""); + }; + Functions.name = function() { + var c = arguments[0]; + var n; + if (arguments.length == 1) { + n = c.contextNode; + } else if (arguments.length == 2) { + n = arguments[1].evaluate(c).first(); + } else { + throw new Error("Function name expects (node-set?)"); + } + if (n == null) { + return new XString(""); + } + if (n.nodeType == NodeTypes.ELEMENT_NODE) { + return new XString(n.nodeName); + } else if (n.nodeType == NodeTypes.ATTRIBUTE_NODE) { + return new XString(n.name || n.nodeName); + } else if (n.nodeType === NodeTypes.PROCESSING_INSTRUCTION_NODE) { + return new XString(n.target || n.nodeName); + } else if (n.localName == null) { + return new XString(""); + } else { + return new XString(n.localName); + } + }; + Functions.string = function() { + var c = arguments[0]; + if (arguments.length == 1) { + return new XString(XNodeSet.prototype.stringForNode(c.contextNode)); + } else if (arguments.length == 2) { + return arguments[1].evaluate(c).string(); + } + throw new Error("Function string expects (object?)"); + }; + Functions.concat = function(c) { + if (arguments.length < 3) { + throw new Error("Function concat expects (string, string[, string]*)"); + } + var s = ""; + for (var i = 1; i < arguments.length; i++) { + s += arguments[i].evaluate(c).stringValue(); + } + return new XString(s); + }; + Functions.startsWith = function() { + var c = arguments[0]; + if (arguments.length != 3) { + throw new Error("Function startsWith expects (string, string)"); + } + var s1 = arguments[1].evaluate(c).stringValue(); + var s2 = arguments[2].evaluate(c).stringValue(); + return new XBoolean(s1.substring(0, s2.length) == s2); + }; + Functions.contains = function() { + var c = arguments[0]; + if (arguments.length != 3) { + throw new Error("Function contains expects (string, string)"); + } + var s1 = arguments[1].evaluate(c).stringValue(); + var s2 = arguments[2].evaluate(c).stringValue(); + return new XBoolean(s1.indexOf(s2) !== -1); + }; + Functions.substringBefore = function() { + var c = arguments[0]; + if (arguments.length != 3) { + throw new Error("Function substring-before expects (string, string)"); + } + var s1 = arguments[1].evaluate(c).stringValue(); + var s2 = arguments[2].evaluate(c).stringValue(); + return new XString(s1.substring(0, s1.indexOf(s2))); + }; + Functions.substringAfter = function() { + var c = arguments[0]; + if (arguments.length != 3) { + throw new Error("Function substring-after expects (string, string)"); + } + var s1 = arguments[1].evaluate(c).stringValue(); + var s2 = arguments[2].evaluate(c).stringValue(); + if (s2.length == 0) { + return new XString(s1); + } + var i = s1.indexOf(s2); + if (i == -1) { + return new XString(""); + } + return new XString(s1.substring(i + s2.length)); + }; + Functions.substring = function() { + var c = arguments[0]; + if (!(arguments.length == 3 || arguments.length == 4)) { + throw new Error("Function substring expects (string, number, number?)"); + } + var s = arguments[1].evaluate(c).stringValue(); + var n1 = Math.round(arguments[2].evaluate(c).numberValue()) - 1; + var n2 = arguments.length == 4 ? n1 + Math.round(arguments[3].evaluate(c).numberValue()) : void 0; + return new XString(s.substring(n1, n2)); + }; + Functions.stringLength = function() { + var c = arguments[0]; + var s; + if (arguments.length == 1) { + s = XNodeSet.prototype.stringForNode(c.contextNode); + } else if (arguments.length == 2) { + s = arguments[1].evaluate(c).stringValue(); + } else { + throw new Error("Function string-length expects (string?)"); + } + return new XNumber(s.length); + }; + Functions.normalizeSpace = function() { + var c = arguments[0]; + var s; + if (arguments.length == 1) { + s = XNodeSet.prototype.stringForNode(c.contextNode); + } else if (arguments.length == 2) { + s = arguments[1].evaluate(c).stringValue(); + } else { + throw new Error("Function normalize-space expects (string?)"); + } + var i = 0; + var j = s.length - 1; + while (Utilities.isSpace(s.charCodeAt(j))) { + j--; + } + var t = ""; + while (i <= j && Utilities.isSpace(s.charCodeAt(i))) { + i++; + } + while (i <= j) { + if (Utilities.isSpace(s.charCodeAt(i))) { + t += " "; + while (i <= j && Utilities.isSpace(s.charCodeAt(i))) { + i++; + } + } else { + t += s.charAt(i); + i++; + } + } + return new XString(t); + }; + Functions.translate = function(c, eValue, eFrom, eTo) { + if (arguments.length != 4) { + throw new Error("Function translate expects (string, string, string)"); + } + var value = eValue.evaluate(c).stringValue(); + var from = eFrom.evaluate(c).stringValue(); + var to = eTo.evaluate(c).stringValue(); + var cMap = reduce(function(acc, ch, i) { + if (!(ch in acc)) { + acc[ch] = i > to.length ? "" : to[i]; + } + return acc; + }, {}, from); + var t = join( + "", + map(function(ch) { + return ch in cMap ? cMap[ch] : ch; + }, value) + ); + return new XString(t); + }; + Functions.boolean_ = function() { + var c = arguments[0]; + if (arguments.length != 2) { + throw new Error("Function boolean expects (object)"); + } + return arguments[1].evaluate(c).bool(); + }; + Functions.not = function(c, eValue) { + if (arguments.length != 2) { + throw new Error("Function not expects (object)"); + } + return eValue.evaluate(c).bool().not(); + }; + Functions.true_ = function() { + if (arguments.length != 1) { + throw new Error("Function true expects ()"); + } + return XBoolean.true_; + }; + Functions.false_ = function() { + if (arguments.length != 1) { + throw new Error("Function false expects ()"); + } + return XBoolean.false_; + }; + Functions.lang = function() { + var c = arguments[0]; + if (arguments.length != 2) { + throw new Error("Function lang expects (string)"); + } + var lang; + for (var n = c.contextNode; n != null && n.nodeType != NodeTypes.DOCUMENT_NODE; n = n.parentNode) { + var a = n.getAttributeNS(XPath.XML_NAMESPACE_URI, "lang"); + if (a != null) { + lang = String(a); + break; + } + } + if (lang == null) { + return XBoolean.false_; + } + var s = arguments[1].evaluate(c).stringValue(); + return new XBoolean(lang.substring(0, s.length) == s && (lang.length == s.length || lang.charAt(s.length) == "-")); + }; + Functions.number = function() { + var c = arguments[0]; + if (!(arguments.length == 1 || arguments.length == 2)) { + throw new Error("Function number expects (object?)"); + } + if (arguments.length == 1) { + return new XNumber(XNodeSet.prototype.stringForNode(c.contextNode)); + } + return arguments[1].evaluate(c).number(); + }; + Functions.sum = function() { + var c = arguments[0]; + var ns; + if (arguments.length != 2 || !Utilities.instance_of(ns = arguments[1].evaluate(c), XNodeSet)) { + throw new Error("Function sum expects (node-set)"); + } + ns = ns.toUnsortedArray(); + var n = 0; + for (var i = 0; i < ns.length; i++) { + n += new XNumber(XNodeSet.prototype.stringForNode(ns[i])).numberValue(); + } + return new XNumber(n); + }; + Functions.floor = function() { + var c = arguments[0]; + if (arguments.length != 2) { + throw new Error("Function floor expects (number)"); + } + return new XNumber(Math.floor(arguments[1].evaluate(c).numberValue())); + }; + Functions.ceiling = function() { + var c = arguments[0]; + if (arguments.length != 2) { + throw new Error("Function ceiling expects (number)"); + } + return new XNumber(Math.ceil(arguments[1].evaluate(c).numberValue())); + }; + Functions.round = function() { + var c = arguments[0]; + if (arguments.length != 2) { + throw new Error("Function round expects (number)"); + } + return new XNumber(Math.round(arguments[1].evaluate(c).numberValue())); + }; + var Utilities = new Object(); + var isAttributeLike = function(val) { + return val && (val.nodeType === NodeTypes.ATTRIBUTE_NODE || val.ownerElement || val.isXPathNamespace); + }; + Utilities.splitQName = function(qn) { + var i = qn.indexOf(":"); + if (i == -1) { + return [null, qn]; + } + return [qn.substring(0, i), qn.substring(i + 1)]; + }; + Utilities.resolveQName = function(qn, nr, n, useDefault) { + var parts = Utilities.splitQName(qn); + if (parts[0] != null) { + parts[0] = nr.getNamespace(parts[0], n); + } else { + if (useDefault) { + parts[0] = nr.getNamespace("", n); + if (parts[0] == null) { + parts[0] = ""; + } + } else { + parts[0] = ""; + } + } + return parts; + }; + Utilities.isSpace = function(c) { + return c == 9 || c == 13 || c == 10 || c == 32; + }; + Utilities.isLetter = function(c) { + return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c >= 192 && c <= 214 || c >= 216 && c <= 246 || c >= 248 && c <= 255 || c >= 256 && c <= 305 || c >= 308 && c <= 318 || c >= 321 && c <= 328 || c >= 330 && c <= 382 || c >= 384 && c <= 451 || c >= 461 && c <= 496 || c >= 500 && c <= 501 || c >= 506 && c <= 535 || c >= 592 && c <= 680 || c >= 699 && c <= 705 || c == 902 || c >= 904 && c <= 906 || c == 908 || c >= 910 && c <= 929 || c >= 931 && c <= 974 || c >= 976 && c <= 982 || c == 986 || c == 988 || c == 990 || c == 992 || c >= 994 && c <= 1011 || c >= 1025 && c <= 1036 || c >= 1038 && c <= 1103 || c >= 1105 && c <= 1116 || c >= 1118 && c <= 1153 || c >= 1168 && c <= 1220 || c >= 1223 && c <= 1224 || c >= 1227 && c <= 1228 || c >= 1232 && c <= 1259 || c >= 1262 && c <= 1269 || c >= 1272 && c <= 1273 || c >= 1329 && c <= 1366 || c == 1369 || c >= 1377 && c <= 1414 || c >= 1488 && c <= 1514 || c >= 1520 && c <= 1522 || c >= 1569 && c <= 1594 || c >= 1601 && c <= 1610 || c >= 1649 && c <= 1719 || c >= 1722 && c <= 1726 || c >= 1728 && c <= 1742 || c >= 1744 && c <= 1747 || c == 1749 || c >= 1765 && c <= 1766 || c >= 2309 && c <= 2361 || c == 2365 || c >= 2392 && c <= 2401 || c >= 2437 && c <= 2444 || c >= 2447 && c <= 2448 || c >= 2451 && c <= 2472 || c >= 2474 && c <= 2480 || c == 2482 || c >= 2486 && c <= 2489 || c >= 2524 && c <= 2525 || c >= 2527 && c <= 2529 || c >= 2544 && c <= 2545 || c >= 2565 && c <= 2570 || c >= 2575 && c <= 2576 || c >= 2579 && c <= 2600 || c >= 2602 && c <= 2608 || c >= 2610 && c <= 2611 || c >= 2613 && c <= 2614 || c >= 2616 && c <= 2617 || c >= 2649 && c <= 2652 || c == 2654 || c >= 2674 && c <= 2676 || c >= 2693 && c <= 2699 || c == 2701 || c >= 2703 && c <= 2705 || c >= 2707 && c <= 2728 || c >= 2730 && c <= 2736 || c >= 2738 && c <= 2739 || c >= 2741 && c <= 2745 || c == 2749 || c == 2784 || c >= 2821 && c <= 2828 || c >= 2831 && c <= 2832 || c >= 2835 && c <= 2856 || c >= 2858 && c <= 2864 || c >= 2866 && c <= 2867 || c >= 2870 && c <= 2873 || c == 2877 || c >= 2908 && c <= 2909 || c >= 2911 && c <= 2913 || c >= 2949 && c <= 2954 || c >= 2958 && c <= 2960 || c >= 2962 && c <= 2965 || c >= 2969 && c <= 2970 || c == 2972 || c >= 2974 && c <= 2975 || c >= 2979 && c <= 2980 || c >= 2984 && c <= 2986 || c >= 2990 && c <= 2997 || c >= 2999 && c <= 3001 || c >= 3077 && c <= 3084 || c >= 3086 && c <= 3088 || c >= 3090 && c <= 3112 || c >= 3114 && c <= 3123 || c >= 3125 && c <= 3129 || c >= 3168 && c <= 3169 || c >= 3205 && c <= 3212 || c >= 3214 && c <= 3216 || c >= 3218 && c <= 3240 || c >= 3242 && c <= 3251 || c >= 3253 && c <= 3257 || c == 3294 || c >= 3296 && c <= 3297 || c >= 3333 && c <= 3340 || c >= 3342 && c <= 3344 || c >= 3346 && c <= 3368 || c >= 3370 && c <= 3385 || c >= 3424 && c <= 3425 || c >= 3585 && c <= 3630 || c == 3632 || c >= 3634 && c <= 3635 || c >= 3648 && c <= 3653 || c >= 3713 && c <= 3714 || c == 3716 || c >= 3719 && c <= 3720 || c == 3722 || c == 3725 || c >= 3732 && c <= 3735 || c >= 3737 && c <= 3743 || c >= 3745 && c <= 3747 || c == 3749 || c == 3751 || c >= 3754 && c <= 3755 || c >= 3757 && c <= 3758 || c == 3760 || c >= 3762 && c <= 3763 || c == 3773 || c >= 3776 && c <= 3780 || c >= 3904 && c <= 3911 || c >= 3913 && c <= 3945 || c >= 4256 && c <= 4293 || c >= 4304 && c <= 4342 || c == 4352 || c >= 4354 && c <= 4355 || c >= 4357 && c <= 4359 || c == 4361 || c >= 4363 && c <= 4364 || c >= 4366 && c <= 4370 || c == 4412 || c == 4414 || c == 4416 || c == 4428 || c == 4430 || c == 4432 || c >= 4436 && c <= 4437 || c == 4441 || c >= 4447 && c <= 4449 || c == 4451 || c == 4453 || c == 4455 || c == 4457 || c >= 4461 && c <= 4462 || c >= 4466 && c <= 4467 || c == 4469 || c == 4510 || c == 4520 || c == 4523 || c >= 4526 && c <= 4527 || c >= 4535 && c <= 4536 || c == 4538 || c >= 4540 && c <= 4546 || c == 4587 || c == 4592 || c == 4601 || c >= 7680 && c <= 7835 || c >= 7840 && c <= 7929 || c >= 7936 && c <= 7957 || c >= 7960 && c <= 7965 || c >= 7968 && c <= 8005 || c >= 8008 && c <= 8013 || c >= 8016 && c <= 8023 || c == 8025 || c == 8027 || c == 8029 || c >= 8031 && c <= 8061 || c >= 8064 && c <= 8116 || c >= 8118 && c <= 8124 || c == 8126 || c >= 8130 && c <= 8132 || c >= 8134 && c <= 8140 || c >= 8144 && c <= 8147 || c >= 8150 && c <= 8155 || c >= 8160 && c <= 8172 || c >= 8178 && c <= 8180 || c >= 8182 && c <= 8188 || c == 8486 || c >= 8490 && c <= 8491 || c == 8494 || c >= 8576 && c <= 8578 || c >= 12353 && c <= 12436 || c >= 12449 && c <= 12538 || c >= 12549 && c <= 12588 || c >= 44032 && c <= 55203 || c >= 19968 && c <= 40869 || c == 12295 || c >= 12321 && c <= 12329; + }; + Utilities.isNCNameChar = function(c) { + return c >= 48 && c <= 57 || c >= 1632 && c <= 1641 || c >= 1776 && c <= 1785 || c >= 2406 && c <= 2415 || c >= 2534 && c <= 2543 || c >= 2662 && c <= 2671 || c >= 2790 && c <= 2799 || c >= 2918 && c <= 2927 || c >= 3047 && c <= 3055 || c >= 3174 && c <= 3183 || c >= 3302 && c <= 3311 || c >= 3430 && c <= 3439 || c >= 3664 && c <= 3673 || c >= 3792 && c <= 3801 || c >= 3872 && c <= 3881 || c == 46 || c == 45 || c == 95 || Utilities.isLetter(c) || c >= 768 && c <= 837 || c >= 864 && c <= 865 || c >= 1155 && c <= 1158 || c >= 1425 && c <= 1441 || c >= 1443 && c <= 1465 || c >= 1467 && c <= 1469 || c == 1471 || c >= 1473 && c <= 1474 || c == 1476 || c >= 1611 && c <= 1618 || c == 1648 || c >= 1750 && c <= 1756 || c >= 1757 && c <= 1759 || c >= 1760 && c <= 1764 || c >= 1767 && c <= 1768 || c >= 1770 && c <= 1773 || c >= 2305 && c <= 2307 || c == 2364 || c >= 2366 && c <= 2380 || c == 2381 || c >= 2385 && c <= 2388 || c >= 2402 && c <= 2403 || c >= 2433 && c <= 2435 || c == 2492 || c == 2494 || c == 2495 || c >= 2496 && c <= 2500 || c >= 2503 && c <= 2504 || c >= 2507 && c <= 2509 || c == 2519 || c >= 2530 && c <= 2531 || c == 2562 || c == 2620 || c == 2622 || c == 2623 || c >= 2624 && c <= 2626 || c >= 2631 && c <= 2632 || c >= 2635 && c <= 2637 || c >= 2672 && c <= 2673 || c >= 2689 && c <= 2691 || c == 2748 || c >= 2750 && c <= 2757 || c >= 2759 && c <= 2761 || c >= 2763 && c <= 2765 || c >= 2817 && c <= 2819 || c == 2876 || c >= 2878 && c <= 2883 || c >= 2887 && c <= 2888 || c >= 2891 && c <= 2893 || c >= 2902 && c <= 2903 || c >= 2946 && c <= 2947 || c >= 3006 && c <= 3010 || c >= 3014 && c <= 3016 || c >= 3018 && c <= 3021 || c == 3031 || c >= 3073 && c <= 3075 || c >= 3134 && c <= 3140 || c >= 3142 && c <= 3144 || c >= 3146 && c <= 3149 || c >= 3157 && c <= 3158 || c >= 3202 && c <= 3203 || c >= 3262 && c <= 3268 || c >= 3270 && c <= 3272 || c >= 3274 && c <= 3277 || c >= 3285 && c <= 3286 || c >= 3330 && c <= 3331 || c >= 3390 && c <= 3395 || c >= 3398 && c <= 3400 || c >= 3402 && c <= 3405 || c == 3415 || c == 3633 || c >= 3636 && c <= 3642 || c >= 3655 && c <= 3662 || c == 3761 || c >= 3764 && c <= 3769 || c >= 3771 && c <= 3772 || c >= 3784 && c <= 3789 || c >= 3864 && c <= 3865 || c == 3893 || c == 3895 || c == 3897 || c == 3902 || c == 3903 || c >= 3953 && c <= 3972 || c >= 3974 && c <= 3979 || c >= 3984 && c <= 3989 || c == 3991 || c >= 3993 && c <= 4013 || c >= 4017 && c <= 4023 || c == 4025 || c >= 8400 && c <= 8412 || c == 8417 || c >= 12330 && c <= 12335 || c == 12441 || c == 12442 || c == 183 || c == 720 || c == 721 || c == 903 || c == 1600 || c == 3654 || c == 3782 || c == 12293 || c >= 12337 && c <= 12341 || c >= 12445 && c <= 12446 || c >= 12540 && c <= 12542; + }; + Utilities.coalesceText = function(n) { + for (var m = n.firstChild; m != null; m = m.nextSibling) { + if (m.nodeType == NodeTypes.TEXT_NODE || m.nodeType == NodeTypes.CDATA_SECTION_NODE) { + var s = m.nodeValue; + var first = m; + m = m.nextSibling; + while (m != null && (m.nodeType == NodeTypes.TEXT_NODE || m.nodeType == NodeTypes.CDATA_SECTION_NODE)) { + s += m.nodeValue; + var del = m; + m = m.nextSibling; + del.parentNode.removeChild(del); + } + if (first.nodeType == NodeTypes.CDATA_SECTION_NODE) { + var p = first.parentNode; + if (first.nextSibling == null) { + p.removeChild(first); + p.appendChild(p.ownerDocument.createTextNode(s)); + } else { + var next = first.nextSibling; + p.removeChild(first); + p.insertBefore(p.ownerDocument.createTextNode(s), next); + } + } else { + first.nodeValue = s; + } + if (m == null) { + break; + } + } else if (m.nodeType == NodeTypes.ELEMENT_NODE) { + Utilities.coalesceText(m); + } + } + }; + Utilities.instance_of = function(o, c) { + while (o != null) { + if (o.constructor === c) { + return true; + } + if (o === Object) { + return false; + } + o = o.constructor.superclass; + } + return false; + }; + Utilities.getElementById = function(n, id) { + if (n.nodeType == NodeTypes.ELEMENT_NODE) { + if (n.getAttribute("id") == id || n.getAttributeNS(null, "id") == id) { + return n; + } + } + for (var m = n.firstChild; m != null; m = m.nextSibling) { + var res = Utilities.getElementById(m, id); + if (res != null) { + return res; + } + } + return null; + }; + var XPathException = function() { + function getMessage(code, exception) { + var msg = exception ? ": " + exception.toString() : ""; + switch (code) { + case XPathException2.INVALID_EXPRESSION_ERR: + return "Invalid expression" + msg; + case XPathException2.TYPE_ERR: + return "Type error" + msg; + } + return null; + } + function XPathException2(code, error, message) { + var err = Error.call(this, getMessage(code, error) || message); + err.code = code; + err.exception = error; + return err; + } + XPathException2.prototype = Object.create(Error.prototype); + XPathException2.prototype.constructor = XPathException2; + XPathException2.superclass = Error; + XPathException2.prototype.toString = function() { + return this.message; + }; + XPathException2.fromMessage = function(message, error) { + return new XPathException2(null, error, message); + }; + XPathException2.INVALID_EXPRESSION_ERR = 51; + XPathException2.TYPE_ERR = 52; + return XPathException2; + }(); + XPathExpression.prototype = {}; + XPathExpression.prototype.constructor = XPathExpression; + XPathExpression.superclass = Object.prototype; + function XPathExpression(e, r, p) { + this.xpath = p.parse(e); + this.context = new XPathContext(); + this.context.namespaceResolver = new XPathNSResolverWrapper(r); + } + XPathExpression.getOwnerDocument = function(n) { + return n.nodeType === NodeTypes.DOCUMENT_NODE ? n : n.ownerDocument; + }; + XPathExpression.detectHtmlDom = function(n) { + if (!n) { + return false; + } + var doc = XPathExpression.getOwnerDocument(n); + try { + return doc.implementation.hasFeature("HTML", "2.0"); + } catch (e) { + return true; + } + }; + XPathExpression.prototype.evaluate = function(n, t, res) { + this.context.expressionContextNode = n; + this.context.caseInsensitive = XPathExpression.detectHtmlDom(n); + var result = this.xpath.evaluate(this.context); + return new XPathResult(result, t); + }; + XPathNSResolverWrapper.prototype = {}; + XPathNSResolverWrapper.prototype.constructor = XPathNSResolverWrapper; + XPathNSResolverWrapper.superclass = Object.prototype; + function XPathNSResolverWrapper(r) { + this.xpathNSResolver = r; + } + XPathNSResolverWrapper.prototype.getNamespace = function(prefix, n) { + if (this.xpathNSResolver == null) { + return null; + } + return this.xpathNSResolver.lookupNamespaceURI(prefix); + }; + NodeXPathNSResolver.prototype = {}; + NodeXPathNSResolver.prototype.constructor = NodeXPathNSResolver; + NodeXPathNSResolver.superclass = Object.prototype; + function NodeXPathNSResolver(n) { + this.node = n; + this.namespaceResolver = new NamespaceResolver(); + } + NodeXPathNSResolver.prototype.lookupNamespaceURI = function(prefix) { + return this.namespaceResolver.getNamespace(prefix, this.node); + }; + XPathResult.prototype = {}; + XPathResult.prototype.constructor = XPathResult; + XPathResult.superclass = Object.prototype; + function XPathResult(v, t) { + if (t == XPathResult.ANY_TYPE) { + if (v.constructor === XString) { + t = XPathResult.STRING_TYPE; + } else if (v.constructor === XNumber) { + t = XPathResult.NUMBER_TYPE; + } else if (v.constructor === XBoolean) { + t = XPathResult.BOOLEAN_TYPE; + } else if (v.constructor === XNodeSet) { + t = XPathResult.UNORDERED_NODE_ITERATOR_TYPE; + } + } + this.resultType = t; + switch (t) { + case XPathResult.NUMBER_TYPE: + this.numberValue = v.numberValue(); + return; + case XPathResult.STRING_TYPE: + this.stringValue = v.stringValue(); + return; + case XPathResult.BOOLEAN_TYPE: + this.booleanValue = v.booleanValue(); + return; + case XPathResult.ANY_UNORDERED_NODE_TYPE: + case XPathResult.FIRST_ORDERED_NODE_TYPE: + if (v.constructor === XNodeSet) { + this.singleNodeValue = v.first(); + return; + } + break; + case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: + case XPathResult.ORDERED_NODE_ITERATOR_TYPE: + if (v.constructor === XNodeSet) { + this.invalidIteratorState = false; + this.nodes = v.toArray(); + this.iteratorIndex = 0; + return; + } + break; + case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE: + case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE: + if (v.constructor === XNodeSet) { + this.nodes = v.toArray(); + this.snapshotLength = this.nodes.length; + return; + } + break; + } + throw new XPathException(XPathException.TYPE_ERR); + } + ; + XPathResult.prototype.iterateNext = function() { + if (this.resultType != XPathResult.UNORDERED_NODE_ITERATOR_TYPE && this.resultType != XPathResult.ORDERED_NODE_ITERATOR_TYPE) { + throw new XPathException(XPathException.TYPE_ERR); + } + return this.nodes[this.iteratorIndex++]; + }; + XPathResult.prototype.snapshotItem = function(i) { + if (this.resultType != XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE && this.resultType != XPathResult.ORDERED_NODE_SNAPSHOT_TYPE) { + throw new XPathException(XPathException.TYPE_ERR); + } + return this.nodes[i]; + }; + XPathResult.ANY_TYPE = 0; + XPathResult.NUMBER_TYPE = 1; + XPathResult.STRING_TYPE = 2; + XPathResult.BOOLEAN_TYPE = 3; + XPathResult.UNORDERED_NODE_ITERATOR_TYPE = 4; + XPathResult.ORDERED_NODE_ITERATOR_TYPE = 5; + XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE = 6; + XPathResult.ORDERED_NODE_SNAPSHOT_TYPE = 7; + XPathResult.ANY_UNORDERED_NODE_TYPE = 8; + XPathResult.FIRST_ORDERED_NODE_TYPE = 9; + function installDOM3XPathSupport(doc, p) { + doc.createExpression = function(e, r) { + try { + return new XPathExpression(e, r, p); + } catch (e2) { + throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, e2); + } + }; + doc.createNSResolver = function(n) { + return new NodeXPathNSResolver(n); + }; + doc.evaluate = function(e, cn, r, t, res) { + if (t < 0 || t > 9) { + throw { code: 0, toString: function() { + return "Request type not supported"; + } }; + } + return doc.createExpression(e, r, p).evaluate(cn, t, res); + }; + } + ; + try { + var shouldInstall = true; + try { + if (document.implementation && document.implementation.hasFeature && document.implementation.hasFeature("XPath", null)) { + shouldInstall = false; + } + } catch (e) { + } + if (shouldInstall) { + installDOM3XPathSupport(document, new XPathParser()); + } + } catch (e) { + } + installDOM3XPathSupport(exports3, new XPathParser()); + (function() { + var parser = new XPathParser(); + var defaultNSResolver = new NamespaceResolver(); + var defaultFunctionResolver = new FunctionResolver(); + var defaultVariableResolver = new VariableResolver(); + function makeNSResolverFromFunction(func) { + return { + getNamespace: function(prefix, node) { + var ns = func(prefix, node); + return ns || defaultNSResolver.getNamespace(prefix, node); + } + }; + } + function makeNSResolverFromObject(obj) { + return makeNSResolverFromFunction(obj.getNamespace.bind(obj)); + } + function makeNSResolverFromMap(map2) { + return makeNSResolverFromFunction(function(prefix) { + return map2[prefix]; + }); + } + function makeNSResolver(resolver) { + if (resolver && typeof resolver.getNamespace === "function") { + return makeNSResolverFromObject(resolver); + } + if (typeof resolver === "function") { + return makeNSResolverFromFunction(resolver); + } + if (typeof resolver === "object") { + return makeNSResolverFromMap(resolver); + } + return defaultNSResolver; + } + function convertValue(value) { + if (value === null || typeof value === "undefined" || value instanceof XString || value instanceof XBoolean || value instanceof XNumber || value instanceof XNodeSet) { + return value; + } + switch (typeof value) { + case "string": + return new XString(value); + case "boolean": + return new XBoolean(value); + case "number": + return new XNumber(value); + } + var ns = new XNodeSet(); + ns.addArray([].concat(value)); + return ns; + } + function makeEvaluator(func) { + return function(context) { + var args = Array.prototype.slice.call(arguments, 1).map(function(arg) { + return arg.evaluate(context); + }); + var result = func.apply(this, [].concat(context, args)); + return convertValue(result); + }; + } + function makeFunctionResolverFromFunction(func) { + return { + getFunction: function(name2, namespace) { + var found = func(name2, namespace); + if (found) { + return makeEvaluator(found); + } + return defaultFunctionResolver.getFunction(name2, namespace); + } + }; + } + function makeFunctionResolverFromObject(obj) { + return makeFunctionResolverFromFunction(obj.getFunction.bind(obj)); + } + function makeFunctionResolverFromMap(map2) { + return makeFunctionResolverFromFunction(function(name2) { + return map2[name2]; + }); + } + function makeFunctionResolver(resolver) { + if (resolver && typeof resolver.getFunction === "function") { + return makeFunctionResolverFromObject(resolver); + } + if (typeof resolver === "function") { + return makeFunctionResolverFromFunction(resolver); + } + if (typeof resolver === "object") { + return makeFunctionResolverFromMap(resolver); + } + return defaultFunctionResolver; + } + function makeVariableResolverFromFunction(func) { + return { + getVariable: function(name2, namespace) { + var value = func(name2, namespace); + return convertValue(value); + } + }; + } + function makeVariableResolver(resolver) { + if (resolver) { + if (typeof resolver.getVariable === "function") { + return makeVariableResolverFromFunction(resolver.getVariable.bind(resolver)); + } + if (typeof resolver === "function") { + return makeVariableResolverFromFunction(resolver); + } + if (typeof resolver === "object") { + return makeVariableResolverFromFunction(function(name2) { + return resolver[name2]; + }); + } + } + return defaultVariableResolver; + } + function copyIfPresent(prop, dest, source) { + if (prop in source) { + dest[prop] = source[prop]; + } + } + function makeContext(options) { + var context = new XPathContext(); + if (options) { + context.namespaceResolver = makeNSResolver(options.namespaces); + context.functionResolver = makeFunctionResolver(options.functions); + context.variableResolver = makeVariableResolver(options.variables); + context.expressionContextNode = options.node; + copyIfPresent("allowAnyNamespaceForNoPrefix", context, options); + copyIfPresent("isHtml", context, options); + } else { + context.namespaceResolver = defaultNSResolver; + } + return context; + } + function evaluate(parsedExpression, options) { + var context = makeContext(options); + return parsedExpression.evaluate(context); + } + var evaluatorPrototype = { + evaluate: function(options) { + return evaluate(this.expression, options); + }, + evaluateNumber: function(options) { + return this.evaluate(options).numberValue(); + }, + evaluateString: function(options) { + return this.evaluate(options).stringValue(); + }, + evaluateBoolean: function(options) { + return this.evaluate(options).booleanValue(); + }, + evaluateNodeSet: function(options) { + return this.evaluate(options).nodeset(); + }, + select: function(options) { + return this.evaluateNodeSet(options).toArray(); + }, + select1: function(options) { + return this.select(options)[0]; + } + }; + function parse(xpath3) { + var parsed = parser.parse(xpath3); + return Object.create(evaluatorPrototype, { + expression: { + value: parsed + } + }); + } + exports3.parse = parse; + })(); + assign( + exports3, + { + XPath, + XPathParser, + XPathResult, + Step, + PathExpr, + NodeTest, + LocationPath, + OrOperation, + AndOperation, + BarOperation, + EqualsOperation, + NotEqualOperation, + LessThanOperation, + GreaterThanOperation, + LessThanOrEqualOperation, + GreaterThanOrEqualOperation, + PlusOperation, + MinusOperation, + MultiplyOperation, + DivOperation, + ModOperation, + UnaryMinusOperation, + FunctionCall, + VariableReference, + XPathContext, + XNodeSet, + XBoolean, + XString, + XNumber, + NamespaceResolver, + FunctionResolver, + VariableResolver, + Utilities + } + ); + exports3.select = function(e, doc, single) { + return exports3.selectWithResolver(e, doc, null, single); + }; + exports3.useNamespaces = function(mappings) { + var resolver = { + mappings: mappings || {}, + lookupNamespaceURI: function(prefix) { + return this.mappings[prefix]; + } + }; + return function(e, doc, single) { + return exports3.selectWithResolver(e, doc, resolver, single); + }; + }; + exports3.selectWithResolver = function(e, doc, resolver, single) { + var expression = new XPathExpression(e, resolver, new XPathParser()); + var type = XPathResult.ANY_TYPE; + var result = expression.evaluate(doc, type, null); + if (result.resultType == XPathResult.STRING_TYPE) { + result = result.stringValue; + } else if (result.resultType == XPathResult.NUMBER_TYPE) { + result = result.numberValue; + } else if (result.resultType == XPathResult.BOOLEAN_TYPE) { + result = result.booleanValue; + } else { + result = result.nodes; + if (single) { + result = result[0]; + } + } + return result; + }; + exports3.select1 = function(e, doc) { + return exports3.select(e, doc, true); + }; + var isArrayOfNodes = function(value) { + return Array.isArray(value) && value.every(isNodeLike); + }; + var isNodeOfType = function(type) { + return function(value) { + return isNodeLike(value) && value.nodeType === type; + }; + }; + assign( + exports3, + { + isNodeLike, + isArrayOfNodes, + isElement: isNodeOfType(NodeTypes.ELEMENT_NODE), + isAttribute: isNodeOfType(NodeTypes.ATTRIBUTE_NODE), + isTextNode: isNodeOfType(NodeTypes.TEXT_NODE), + isCDATASection: isNodeOfType(NodeTypes.CDATA_SECTION_NODE), + isProcessingInstruction: isNodeOfType(NodeTypes.PROCESSING_INSTRUCTION_NODE), + isComment: isNodeOfType(NodeTypes.COMMENT_NODE), + isDocumentNode: isNodeOfType(NodeTypes.DOCUMENT_NODE), + isDocumentTypeNode: isNodeOfType(NodeTypes.DOCUMENT_TYPE_NODE), + isDocumentFragment: isNodeOfType(NodeTypes.DOCUMENT_FRAGMENT_NODE) + } + ); + })(xpath2); + } +}); + +// src/index.ts +var src_exports = {}; +__export(src_exports, { + plugin: () => plugin +}); +module.exports = __toCommonJS(src_exports); +var import_xmldom = __toESM(require_lib()); +var import_xpath = __toESM(require_xpath()); +var plugin = { + templateFunctions: [{ + name: "xml.xpath", + description: "Filter XML-formatted text using XPath syntax", + args: [ + { type: "text", name: "input", label: "Input", multiLine: true, placeholder: "" }, + { type: "text", name: "query", label: "Query", placeholder: "//foo" } + ], + async onRender(_ctx, args) { + try { + const doc = new import_xmldom.DOMParser().parseFromString(String(args.values.input), "text/xml"); + let result = import_xpath.default.select(String(args.values.query), doc, false); + if (Array.isArray(result)) { + return String(result[0]); + } else { + return String(result); + } + } catch (e) { + return null; + } + } + }] +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + plugin +}); diff --git a/src-tauri/vendored/plugins/template-function-xml/package.json b/src-tauri/vendored/plugins/template-function-xml/package.json new file mode 100755 index 000000000..d1274960f --- /dev/null +++ b/src-tauri/vendored/plugins/template-function-xml/package.json @@ -0,0 +1,13 @@ +{ + "name": "@yaakapp/template-function-xml", + "private": true, + "version": "0.0.1", + "scripts": { + "build": "yaakcli build ./src/index.ts", + "dev": "yaakcli dev ./src/index.js" + }, + "dependencies": { + "@xmldom/xmldom": "^0.8.10", + "xpath": "^0.0.34" + } +} diff --git a/src-tauri/yaak-plugins/src/events.rs b/src-tauri/yaak-plugins/src/events.rs index faebabe55..c9786cfb3 100644 --- a/src-tauri/yaak-plugins/src/events.rs +++ b/src-tauri/yaak-plugins/src/events.rs @@ -840,7 +840,7 @@ pub struct CallTemplateFunctionResponse { #[ts(export, export_to = "gen_events.ts")] pub struct CallTemplateFunctionArgs { pub purpose: RenderPurpose, - pub values: HashMap, + pub values: HashMap, } #[derive(Debug, Clone, Serialize, Deserialize, TS)] diff --git a/src-tauri/yaak-plugins/src/manager.rs b/src-tauri/yaak-plugins/src/manager.rs index fb708a2c4..2ac26d7e7 100644 --- a/src-tauri/yaak-plugins/src/manager.rs +++ b/src-tauri/yaak-plugins/src/manager.rs @@ -11,6 +11,7 @@ use crate::events::{ GetHttpRequestActionsResponse, GetTemplateFunctionsResponse, ImportRequest, ImportResponse, InternalEvent, InternalEventPayload, JsonPrimitive, PluginWindowContext, RenderPurpose, }; +use crate::native_template_functions::template_function_secure; use crate::nodejs::start_nodejs_plugin_runtime; use crate::plugin_handle::PluginHandle; use crate::server_ws::PluginRuntimeServerWebsocket; @@ -24,13 +25,12 @@ use tauri::path::BaseDirectory; use tauri::{AppHandle, Manager, Runtime, WebviewWindow}; use tokio::fs::read_dir; use tokio::net::TcpListener; -use tokio::sync::{mpsc, Mutex}; -use tokio::time::{timeout, Instant}; +use tokio::sync::{Mutex, mpsc}; +use tokio::time::{Instant, timeout}; use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::generate_id; use yaak_templates::error::Error::RenderError; use yaak_templates::error::Result as TemplateResult; -use crate::native_template_functions::template_function_secure; #[derive(Clone)] pub struct PluginManager { @@ -160,8 +160,7 @@ impl PluginManager { }) .collect(); - let plugins = - app_handle.db().list_plugins().unwrap_or_default(); + let plugins = app_handle.db().list_plugins().unwrap_or_default(); let installed_plugin_dirs: Vec = plugins .iter() .map(|p| PluginCandidate { @@ -606,15 +605,12 @@ impl PluginManager { &self, window_context: &PluginWindowContext, fn_name: &str, - args: HashMap, + values: HashMap, purpose: RenderPurpose, ) -> TemplateResult { let req = CallTemplateFunctionRequest { name: fn_name.to_string(), - args: CallTemplateFunctionArgs { - purpose, - values: args, - }, + args: CallTemplateFunctionArgs { purpose, values }, }; let events = self diff --git a/src-tauri/yaak-plugins/src/native_template_functions.rs b/src-tauri/yaak-plugins/src/native_template_functions.rs index bb11e92fd..8ee09d991 100644 --- a/src-tauri/yaak-plugins/src/native_template_functions.rs +++ b/src-tauri/yaak-plugins/src/native_template_functions.rs @@ -34,7 +34,7 @@ pub(crate) fn template_function_secure() -> TemplateFunction { pub fn template_function_secure_run( app_handle: &AppHandle, - args: HashMap, + args: HashMap, window_context: &PluginWindowContext, ) -> Result { match window_context.clone() { @@ -43,9 +43,10 @@ pub fn template_function_secure_run( .. } => { let value = args.get("value").map(|v| v.to_owned()).unwrap_or_default(); - if value.is_empty() { - return Ok("".to_string()); - } + let value = match value { + serde_json::Value::String(s) => s, + _ => return Ok("".to_string()), + }; let value = match value.strip_prefix("YENC_") { None => { @@ -118,7 +119,7 @@ pub fn decrypt_secure_template_function( for a in args { match a.clone().value { Val::Str { text } => { - args_map.insert(a.name.to_string(), text); + args_map.insert(a.name.to_string(), serde_json::Value::String(text)); } _ => continue, } diff --git a/src-tauri/yaak-plugins/src/template_callback.rs b/src-tauri/yaak-plugins/src/template_callback.rs index 2800a6fc3..819b5856d 100644 --- a/src-tauri/yaak-plugins/src/template_callback.rs +++ b/src-tauri/yaak-plugins/src/template_callback.rs @@ -30,7 +30,7 @@ impl PluginTemplateCallback { } impl TemplateCallback for PluginTemplateCallback { - async fn run(&self, fn_name: &str, args: HashMap) -> Result { + async fn run(&self, fn_name: &str, args: HashMap) -> Result { // The beta named the function `Response` but was changed in stable. // Keep this here for a while because there's no easy way to migrate let fn_name = if fn_name == "Response" { "response" } else { fn_name }; diff --git a/src-tauri/yaak-templates/src/renderer.rs b/src-tauri/yaak-templates/src/renderer.rs index 959cde8ff..e867a697a 100644 --- a/src-tauri/yaak-templates/src/renderer.rs +++ b/src-tauri/yaak-templates/src/renderer.rs @@ -11,7 +11,7 @@ pub trait TemplateCallback { fn run( &self, fn_name: &str, - args: HashMap, + args: HashMap, ) -> impl Future> + Send; fn transform_arg(&self, fn_name: &str, arg_name: &str, arg_value: &str) -> Result; @@ -107,9 +107,15 @@ async fn render_value( None => return Err(VariableNotFound(name)), }, Val::Fn { name, args } => { - let mut resolved_args: HashMap = HashMap::new(); + let mut resolved_args: HashMap = HashMap::new(); for a in args { - let v = Box::pin(render_value(a.value, vars, cb, depth)).await?; + let v = match a.value.clone() { + Val::Bool { value } => serde_json::Value::Bool(value), + Val::Null => serde_json::Value::Null, + _ => serde_json::Value::String( + Box::pin(render_value(a.value, vars, cb, depth)).await?, + ), + }; resolved_args.insert(a.name, v); } let result = cb.run(name.as_str(), resolved_args.clone()).await?; @@ -133,7 +139,11 @@ mod parse_and_render_tests { struct EmptyCB {} impl TemplateCallback for EmptyCB { - async fn run(&self, _fn_name: &str, _args: HashMap) -> Result { + async fn run( + &self, + _fn_name: &str, + _args: HashMap, + ) -> Result { todo!() } @@ -236,7 +246,11 @@ mod parse_and_render_tests { struct CB {} impl TemplateCallback for CB { - async fn run(&self, fn_name: &str, args: HashMap) -> Result { + async fn run( + &self, + fn_name: &str, + args: HashMap, + ) -> Result { Ok(format!("{fn_name}: {}, {:?} {:?}", args.len(), args.get("a"), args.get("b"))) } @@ -260,7 +274,11 @@ mod parse_and_render_tests { let result = r#"BAR"#; struct CB {} impl TemplateCallback for CB { - async fn run(&self, fn_name: &str, args: HashMap) -> Result { + async fn run( + &self, + fn_name: &str, + args: HashMap, + ) -> Result { Ok(match fn_name { "secret" => "abc".to_string(), "upper" => args["foo"].to_string().to_uppercase(), @@ -290,7 +308,7 @@ mod parse_and_render_tests { let result = r#"FOO 'BAR' BAZ"#; struct CB {} impl TemplateCallback for CB { - async fn run(&self, fn_name: &str, args: HashMap) -> Result { + async fn run(&self, fn_name: &str, args: HashMap) -> Result { Ok(match fn_name { "upper" => args["foo"].to_string().to_uppercase(), _ => "".to_string(), @@ -319,7 +337,7 @@ mod parse_and_render_tests { let result = r#"BAR"#; struct CB {} impl TemplateCallback for CB { - async fn run(&self, fn_name: &str, args: HashMap) -> Result { + async fn run(&self, fn_name: &str, args: HashMap) -> Result { Ok(match fn_name { "secret" => "abc".to_string(), "upper" => args["foo"].to_string().to_uppercase(), @@ -349,7 +367,7 @@ mod parse_and_render_tests { let result = r#"bar"#; struct CB {} impl TemplateCallback for CB { - async fn run(&self, fn_name: &str, args: HashMap) -> Result { + async fn run(&self, fn_name: &str, args: HashMap) -> Result { Ok(match fn_name { "no_op" => args["inner"].to_string(), _ => "".to_string(), @@ -377,7 +395,7 @@ mod parse_and_render_tests { let result = r#"ABC"#; struct CB {} impl TemplateCallback for CB { - async fn run(&self, fn_name: &str, args: HashMap) -> Result { + async fn run(&self, fn_name: &str, args: HashMap) -> Result { Ok(match fn_name { "secret" => "abc".to_string(), "upper" => args["foo"].to_string().to_uppercase(), @@ -406,7 +424,7 @@ mod parse_and_render_tests { struct CB {} impl TemplateCallback for CB { - async fn run(&self, _fn_name: &str, _args: HashMap) -> Result { + async fn run(&self, _fn_name: &str, _args: HashMap) -> Result { Err(RenderError("Failed to do it!".to_string())) } @@ -438,7 +456,7 @@ mod render_json_value_raw_tests { struct EmptyCB {} impl TemplateCallback for EmptyCB { - async fn run(&self, _fn_name: &str, _args: HashMap) -> Result { + async fn run(&self, _fn_name: &str, _args: HashMap) -> Result { todo!() } From 399cd35b2b53530d9a81d5b34ff689f6b2f80d87 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 28 May 2025 13:14:32 -0700 Subject: [PATCH 224/996] Don't return "undefined" when no XPath match --- plugins/template-function-xml/src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/template-function-xml/src/index.ts b/plugins/template-function-xml/src/index.ts index fdb32b4a8..ed87c3a83 100755 --- a/plugins/template-function-xml/src/index.ts +++ b/plugins/template-function-xml/src/index.ts @@ -14,8 +14,9 @@ export const plugin: PluginDefinition = { try { const doc = new DOMParser().parseFromString(String(args.values.input), 'text/xml'); let result = xpath.select(String(args.values.query), doc, false); + console.log("RESULT", result); if (Array.isArray(result)) { - return String(result.map(c => String(c.firstChild))[0]); + return String(result.map(c => String(c.firstChild))[0] ?? ''); } else if (result instanceof Node) { return String(result.firstChild); } else { From bbf2b6dec0abcadb07dd76f94c583f0b9f32503c Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 28 May 2025 13:14:46 -0700 Subject: [PATCH 225/996] Remove console.log --- plugins/template-function-xml/src/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/template-function-xml/src/index.ts b/plugins/template-function-xml/src/index.ts index ed87c3a83..b6595e5a9 100755 --- a/plugins/template-function-xml/src/index.ts +++ b/plugins/template-function-xml/src/index.ts @@ -14,7 +14,6 @@ export const plugin: PluginDefinition = { try { const doc = new DOMParser().parseFromString(String(args.values.input), 'text/xml'); let result = xpath.select(String(args.values.query), doc, false); - console.log("RESULT", result); if (Array.isArray(result)) { return String(result.map(c => String(c.firstChild))[0] ?? ''); } else if (result instanceof Node) { From d07272003bb2e350362ffa136d240c6d1132fcd7 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 28 May 2025 14:06:17 -0700 Subject: [PATCH 226/996] Fix JSONPath function quoting strings --- plugins/template-function-json/src/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/template-function-json/src/index.ts b/plugins/template-function-json/src/index.ts index f2b622e60..8383a0a12 100755 --- a/plugins/template-function-json/src/index.ts +++ b/plugins/template-function-json/src/index.ts @@ -19,6 +19,9 @@ export const plugin: PluginDefinition = { if (Array.isArray(filtered)) { filtered = filtered[0]; } + if (typeof filtered === 'string') { + return filtered; + } if (args.values.formatted) { return JSON.stringify(filtered, null, 2); From 085b640b3ce00cd9ba473b75e1edeebf59dfed2f Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 28 May 2025 14:07:00 -0700 Subject: [PATCH 227/996] Update plugins --- .../template-function-json/build/index.js | 3 + .../template-function-xml/build/index.js | 56 ++++++++++--------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src-tauri/vendored/plugins/template-function-json/build/index.js b/src-tauri/vendored/plugins/template-function-json/build/index.js index c548fddec..1b4f895f0 100644 --- a/src-tauri/vendored/plugins/template-function-json/build/index.js +++ b/src-tauri/vendored/plugins/template-function-json/build/index.js @@ -1740,6 +1740,9 @@ var plugin2 = { if (Array.isArray(filtered)) { filtered = filtered[0]; } + if (typeof filtered === "string") { + return filtered; + } if (args.values.formatted) { return JSON.stringify(filtered, null, 2); } else { diff --git a/src-tauri/vendored/plugins/template-function-xml/build/index.js b/src-tauri/vendored/plugins/template-function-xml/build/index.js index 1bdc3cef1..c4a5731c2 100644 --- a/src-tauri/vendored/plugins/template-function-xml/build/index.js +++ b/src-tauri/vendored/plugins/template-function-xml/build/index.js @@ -522,9 +522,9 @@ var require_dom = __commonJS({ return node; } }; - function Node() { + function Node2() { } - Node.prototype = { + Node2.prototype = { firstChild: null, lastChild: null, previousSibling: null, @@ -633,8 +633,8 @@ var require_dom = __commonJS({ function _xmlEncoder(c) { return c == "<" && "<" || c == ">" && ">" || c == "&" && "&" || c == '"' && """ || "&#" + c.charCodeAt() + ";"; } - copy(NodeType, Node); - copy(NodeType, Node.prototype); + copy(NodeType, Node2); + copy(NodeType, Node2.prototype); function _visitNode(node, callback) { if (callback(node)) { return true; @@ -702,19 +702,19 @@ var require_dom = __commonJS({ return child; } function hasValidParentNodeType(node) { - return node && (node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE); + return node && (node.nodeType === Node2.DOCUMENT_NODE || node.nodeType === Node2.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node2.ELEMENT_NODE); } function hasInsertableNodeType(node) { - return node && (isElementNode(node) || isTextNode(node) || isDocTypeNode(node) || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.COMMENT_NODE || node.nodeType === Node.PROCESSING_INSTRUCTION_NODE); + return node && (isElementNode(node) || isTextNode(node) || isDocTypeNode(node) || node.nodeType === Node2.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node2.COMMENT_NODE || node.nodeType === Node2.PROCESSING_INSTRUCTION_NODE); } function isDocTypeNode(node) { - return node && node.nodeType === Node.DOCUMENT_TYPE_NODE; + return node && node.nodeType === Node2.DOCUMENT_TYPE_NODE; } function isElementNode(node) { - return node && node.nodeType === Node.ELEMENT_NODE; + return node && node.nodeType === Node2.ELEMENT_NODE; } function isTextNode(node) { - return node && node.nodeType === Node.TEXT_NODE; + return node && node.nodeType === Node2.TEXT_NODE; } function isElementInsertionPossible(doc, child) { var parentChildNodes = doc.childNodes || []; @@ -748,7 +748,7 @@ var require_dom = __commonJS({ // the sax parser currently adds top level text nodes, this will be fixed in 0.9.0 // || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE) // or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException. - isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE + isDocTypeNode(node) && parent.nodeType !== Node2.DOCUMENT_NODE ) { throw new DOMException( HIERARCHY_REQUEST_ERR, @@ -759,7 +759,7 @@ var require_dom = __commonJS({ function assertPreInsertionValidityInDocument(parent, node, child) { var parentChildNodes = parent.childNodes || []; var nodeChildNodes = node.childNodes || []; - if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + if (node.nodeType === Node2.DOCUMENT_FRAGMENT_NODE) { var nodeChildElements = nodeChildNodes.filter(isElementNode); if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "More than one element or text in fragment"); @@ -789,7 +789,7 @@ var require_dom = __commonJS({ function assertPreReplacementValidityInDocument(parent, node, child) { var parentChildNodes = parent.childNodes || []; var nodeChildNodes = node.childNodes || []; - if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + if (node.nodeType === Node2.DOCUMENT_FRAGMENT_NODE) { var nodeChildElements = nodeChildNodes.filter(isElementNode); if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "More than one element or text in fragment"); @@ -819,7 +819,7 @@ var require_dom = __commonJS({ } function _insertBefore(parent, node, child, _inDocumentAssertion) { assertPreInsertionValidity1to5(parent, node, child); - if (parent.nodeType === Node.DOCUMENT_NODE) { + if (parent.nodeType === Node2.DOCUMENT_NODE) { (_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child); } var cp = node.parentNode; @@ -1072,7 +1072,7 @@ var require_dom = __commonJS({ return node; } }; - _extends(Document, Node); + _extends(Document, Node2); function Element() { this._nsMap = {}; } @@ -1159,11 +1159,11 @@ var require_dom = __commonJS({ }; Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName; Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS; - _extends(Element, Node); + _extends(Element, Node2); function Attr() { } Attr.prototype.nodeType = ATTRIBUTE_NODE; - _extends(Attr, Node); + _extends(Attr, Node2); function CharacterData() { } CharacterData.prototype = { @@ -1193,7 +1193,7 @@ var require_dom = __commonJS({ this.length = text.length; } }; - _extends(CharacterData, Node); + _extends(CharacterData, Node2); function Text() { } Text.prototype = { @@ -1230,34 +1230,34 @@ var require_dom = __commonJS({ function DocumentType() { } DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE; - _extends(DocumentType, Node); + _extends(DocumentType, Node2); function Notation() { } Notation.prototype.nodeType = NOTATION_NODE; - _extends(Notation, Node); + _extends(Notation, Node2); function Entity() { } Entity.prototype.nodeType = ENTITY_NODE; - _extends(Entity, Node); + _extends(Entity, Node2); function EntityReference() { } EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; - _extends(EntityReference, Node); + _extends(EntityReference, Node2); function DocumentFragment() { } DocumentFragment.prototype.nodeName = "#document-fragment"; DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; - _extends(DocumentFragment, Node); + _extends(DocumentFragment, Node2); function ProcessingInstruction() { } ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; - _extends(ProcessingInstruction, Node); + _extends(ProcessingInstruction, Node2); function XMLSerializer() { } XMLSerializer.prototype.serializeToString = function(node, isHtml, nodeFilter) { return nodeSerializeToString.call(node, isHtml, nodeFilter); }; - Node.prototype.toString = nodeSerializeToString; + Node2.prototype.toString = nodeSerializeToString; function nodeSerializeToString(isHtml, nodeFilter) { var buf = []; var refNode = this.nodeType == 9 && this.documentElement || this; @@ -1535,7 +1535,7 @@ var require_dom = __commonJS({ return this.$$length; } }); - Object.defineProperty(Node.prototype, "textContent", { + Object.defineProperty(Node2.prototype, "textContent", { get: function() { return getTextContent2(this); }, @@ -1568,7 +1568,7 @@ var require_dom = __commonJS({ exports2.DOMException = DOMException; exports2.DOMImplementation = DOMImplementation; exports2.Element = Element; - exports2.Node = Node; + exports2.Node = Node2; exports2.NodeList = NodeList; exports2.XMLSerializer = XMLSerializer; } @@ -8364,7 +8364,9 @@ var plugin = { const doc = new import_xmldom.DOMParser().parseFromString(String(args.values.input), "text/xml"); let result = import_xpath.default.select(String(args.values.query), doc, false); if (Array.isArray(result)) { - return String(result[0]); + return String(result.map((c) => String(c.firstChild))[0] ?? ""); + } else if (result instanceof Node) { + return String(result.firstChild); } else { return String(result); } From bd1986f31fd57720836de831e8ce25d496519c50 Mon Sep 17 00:00:00 2001 From: Andy Bao Date: Thu, 29 May 2025 10:02:27 -0400 Subject: [PATCH 228/996] Fix "Validate TLS Certificates" option for WS and GRPC (#218) --- package-lock.json | 2 +- src-tauri/Cargo.lock | 9 ++-- src-tauri/Cargo.toml | 4 +- src-tauri/src/http_request.rs | 21 +------- src-tauri/src/lib.rs | 8 ++- src-tauri/yaak-grpc/Cargo.toml | 3 +- src-tauri/yaak-grpc/src/client.rs | 6 +-- src-tauri/yaak-grpc/src/manager.rs | 11 ++-- src-tauri/yaak-grpc/src/reflection.rs | 3 +- src-tauri/yaak-grpc/src/transport.rs | 15 ++---- src-tauri/yaak-http/Cargo.toml | 2 + src-tauri/yaak-http/src/lib.rs | 2 + src-tauri/yaak-http/src/tls.rs | 77 +++++++++++++++++++++++++++ src-tauri/yaak-ws/Cargo.toml | 2 - src-tauri/yaak-ws/src/commands.rs | 9 +++- src-tauri/yaak-ws/src/connect.rs | 13 ++--- src-tauri/yaak-ws/src/manager.rs | 3 +- 17 files changed, 124 insertions(+), 66 deletions(-) create mode 100644 src-tauri/yaak-http/src/tls.rs diff --git a/package-lock.json b/package-lock.json index 83cb8d268..78ec5b504 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13826,7 +13826,7 @@ }, "packages/plugin-runtime-types": { "name": "@yaakapp/api", - "version": "0.5.3", + "version": "0.6.0", "dependencies": { "@types/node": "^22.5.4" }, diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 05148f6a2..d6511ad09 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -8052,8 +8052,6 @@ dependencies = [ "rand 0.9.0", "reqwest", "reqwest_cookie_store", - "rustls", - "rustls-platform-verifier", "serde", "serde_json", "tauri", @@ -8144,8 +8142,6 @@ dependencies = [ "prost", "prost-reflect", "prost-types", - "rustls", - "rustls-platform-verifier", "serde", "serde_json", "tauri", @@ -8155,6 +8151,7 @@ dependencies = [ "tonic", "tonic-reflection", "uuid", + "yaak-http", ] [[package]] @@ -8162,6 +8159,8 @@ name = "yaak-http" version = "0.1.0" dependencies = [ "regex", + "rustls", + "rustls-platform-verifier", "urlencoding", "yaak-models", ] @@ -8292,8 +8291,6 @@ dependencies = [ "futures-util", "log", "md5", - "rustls", - "rustls-platform-verifier", "serde", "serde_json", "tauri", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 03a5596e7..b6afbf0b1 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -50,8 +50,6 @@ mime_guess = "2.0.5" rand = "0.9.0" reqwest = { workspace = true, features = ["multipart", "cookies", "gzip", "brotli", "deflate", "json", "rustls-tls-manual-roots-no-provider"] } reqwest_cookie_store = "0.8.0" -rustls = { version = "0.23.25", default-features = false, features = ["custom-provider", "ring"] } -rustls-platform-verifier = "0.5.1" serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, features = ["raw_value"] } tauri = { workspace = true, features = ["devtools", "protocol-asset"] } @@ -93,6 +91,8 @@ tauri-plugin-shell = "2.2.1" tokio = "1.44.2" thiserror = "2.0.12" ts-rs = "10.1.0" +rustls = { version = "0.23.25", default-features = false } +rustls-platform-verifier = "0.5.1" yaak-common = { path = "yaak-common" } yaak-http = { path = "yaak-http" } yaak-models = { path = "yaak-models" } diff --git a/src-tauri/src/http_request.rs b/src-tauri/src/http_request.rs index b650bc924..49a571e97 100644 --- a/src-tauri/src/http_request.rs +++ b/src-tauri/src/http_request.rs @@ -9,9 +9,6 @@ use mime_guess::Mime; use reqwest::redirect::Policy; use reqwest::{Method, Response}; use reqwest::{Proxy, Url, multipart}; -use rustls::ClientConfig; -use rustls::crypto::ring; -use rustls_platform_verifier::BuilderVerifierExt; use serde_json::Value; use std::collections::BTreeMap; use std::path::PathBuf; @@ -112,22 +109,8 @@ pub async fn send_http_request( .referer(false) .tls_info(true); - if workspace.setting_validate_certificates { - // Use platform-native verifier to validate certificates - let arc_crypto_provider = Arc::new(ring::default_provider()); - let config = ClientConfig::builder_with_provider(arc_crypto_provider) - .with_safe_default_protocol_versions() - .unwrap() - .with_platform_verifier() - .with_no_client_auth(); - client_builder = client_builder.use_preconfigured_tls(config) - } else { - // Use rustls to skip validation because rustls_platform_verifier does not have this ability - client_builder = client_builder - .use_rustls_tls() - .danger_accept_invalid_hostnames(true) - .danger_accept_invalid_certs(true); - } + let tls_config = yaak_http::tls::get_config(workspace.setting_validate_certificates); + client_builder = client_builder.use_preconfigured_tls(tls_config); match settings.proxy { Some(ProxySetting::Disabled) => client_builder = client_builder.no_proxy(), diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 6e316b264..ab96b005c 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -155,6 +155,7 @@ async fn cmd_grpc_reflect( let base_environment = app_handle.db().get_base_environment(&unrendered_request.workspace_id)?; + let workspace = app_handle.db().get_workspace(&unrendered_request.workspace_id)?; let req = render_grpc_request( &resolved_request, @@ -179,6 +180,7 @@ async fn cmd_grpc_reflect( &uri, &proto_files.iter().map(|p| PathBuf::from_str(p).unwrap()).collect(), &metadata, + workspace.setting_validate_certificates, ) .await .map_err(|e| GenericError(e.to_string()))?) @@ -201,6 +203,7 @@ async fn cmd_grpc_go( let resolved_request = resolve_grpc_request(&window, &unrendered_request)?; let base_environment = app_handle.db().get_base_environment(&unrendered_request.workspace_id)?; + let workspace = app_handle.db().get_workspace(&unrendered_request.workspace_id)?; let request = render_grpc_request( &resolved_request, @@ -263,6 +266,7 @@ async fn cmd_grpc_go( uri.as_str(), &proto_files.iter().map(|p| PathBuf::from_str(p).unwrap()).collect(), &metadata, + workspace.setting_validate_certificates, ) .await; @@ -296,7 +300,7 @@ async fn cmd_grpc_go( let cancelled_rx = cancelled_rx.clone(); let app_handle = app_handle.clone(); let window = window.clone(); - let workspace = base_environment.clone(); + let base_environment = base_environment.clone(); let environment = environment.clone(); let base_msg = base_msg.clone(); let method_desc = method_desc.clone(); @@ -326,7 +330,7 @@ async fn cmd_grpc_go( tauri::async_runtime::block_on(async { render_template( msg.as_str(), - &workspace, + &base_environment, environment.as_ref(), &PluginTemplateCallback::new( &app_handle, diff --git a/src-tauri/yaak-grpc/Cargo.toml b/src-tauri/yaak-grpc/Cargo.toml index b8c2bb121..d05d73abd 100644 --- a/src-tauri/yaak-grpc/Cargo.toml +++ b/src-tauri/yaak-grpc/Cargo.toml @@ -11,8 +11,6 @@ dunce = "1.0.4" hyper = "1.5.2" hyper-rustls = { version = "0.27.5", default-features = false, features = ["http2"] } hyper-util = { version = "0.1.10", default-features = false, features = ["client-legacy"] } -rustls = { version = "0.23.21", default-features = false, features = ["custom-provider", "ring"] } -rustls-platform-verifier = "0.5.0" log = "0.4.20" md5 = "0.7.0" prost = "0.13.4" @@ -27,3 +25,4 @@ tokio-stream = "0.1.14" tonic = { version = "0.12.3", default-features = false, features = ["transport"] } tonic-reflection = "0.12.3" uuid = { version = "1.7.0", features = ["v4"] } +yaak-http = { workspace = true } \ No newline at end of file diff --git a/src-tauri/yaak-grpc/src/client.rs b/src-tauri/yaak-grpc/src/client.rs index 5c185368e..fbe978a99 100644 --- a/src-tauri/yaak-grpc/src/client.rs +++ b/src-tauri/yaak-grpc/src/client.rs @@ -26,13 +26,13 @@ pub struct AutoReflectionClient, BoxBod } impl AutoReflectionClient { - pub fn new(uri: &Uri) -> Self { + pub fn new(uri: &Uri, validate_certificates: bool) -> Self { let client_v1 = v1::server_reflection_client::ServerReflectionClient::with_origin( - get_transport(), + get_transport(validate_certificates), uri.clone(), ); let client_v1alpha = v1alpha::server_reflection_client::ServerReflectionClient::with_origin( - get_transport(), + get_transport(validate_certificates), uri.clone(), ); AutoReflectionClient { diff --git a/src-tauri/yaak-grpc/src/manager.rs b/src-tauri/yaak-grpc/src/manager.rs index c4e19efc1..e915966b5 100644 --- a/src-tauri/yaak-grpc/src/manager.rs +++ b/src-tauri/yaak-grpc/src/manager.rs @@ -181,10 +181,11 @@ impl GrpcHandle { uri: &str, proto_files: &Vec, metadata: &BTreeMap, + validate_certificates: bool, ) -> Result<(), String> { let pool = if proto_files.is_empty() { let full_uri = uri_from_str(uri)?; - fill_pool_from_reflection(&full_uri, metadata).await + fill_pool_from_reflection(&full_uri, metadata, validate_certificates).await } else { fill_pool_from_files(&self.app_handle, proto_files).await }?; @@ -199,9 +200,10 @@ impl GrpcHandle { uri: &str, proto_files: &Vec, metadata: &BTreeMap, + validate_certificates: bool, ) -> Result, String> { // Ensure reflection is up-to-date - self.reflect(id, uri, proto_files, metadata).await?; + self.reflect(id, uri, proto_files, metadata, validate_certificates).await?; let pool = self.get_pool(id, uri, proto_files).ok_or("Failed to get pool".to_string())?; Ok(self.services_from_pool(&pool)) @@ -238,12 +240,13 @@ impl GrpcHandle { uri: &str, proto_files: &Vec, metadata: &BTreeMap, + validate_certificates: bool, ) -> Result { - self.reflect(id, uri, proto_files, metadata).await?; + self.reflect(id, uri, proto_files, metadata, validate_certificates).await?; let pool = self.get_pool(id, uri, proto_files).ok_or("Failed to get pool")?; let uri = uri_from_str(uri)?; - let conn = get_transport(); + let conn = get_transport(validate_certificates); let connection = GrpcConnection { pool: pool.clone(), conn, diff --git a/src-tauri/yaak-grpc/src/reflection.rs b/src-tauri/yaak-grpc/src/reflection.rs index 1449a6d85..57c827b6a 100644 --- a/src-tauri/yaak-grpc/src/reflection.rs +++ b/src-tauri/yaak-grpc/src/reflection.rs @@ -93,9 +93,10 @@ pub async fn fill_pool_from_files( pub async fn fill_pool_from_reflection( uri: &Uri, metadata: &BTreeMap, + validate_certificates: bool, ) -> Result { let mut pool = DescriptorPool::new(); - let mut client = AutoReflectionClient::new(uri); + let mut client = AutoReflectionClient::new(uri, validate_certificates); for service in list_services(&mut client, metadata).await? { if service == "grpc.reflection.v1alpha.ServerReflection" { diff --git a/src-tauri/yaak-grpc/src/transport.rs b/src-tauri/yaak-grpc/src/transport.rs index de30e06d8..2541003b5 100644 --- a/src-tauri/yaak-grpc/src/transport.rs +++ b/src-tauri/yaak-grpc/src/transport.rs @@ -2,25 +2,16 @@ use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder}; use hyper_util::client::legacy::connect::HttpConnector; use hyper_util::client::legacy::Client; use hyper_util::rt::TokioExecutor; -use rustls::crypto::ring; -use rustls::ClientConfig; -use rustls_platform_verifier::BuilderVerifierExt; -use std::sync::Arc; use tonic::body::BoxBody; -pub(crate) fn get_transport() -> Client, BoxBody> { - let arc_crypto_provider = Arc::new(ring::default_provider()); - let config = ClientConfig::builder_with_provider(arc_crypto_provider) - .with_safe_default_protocol_versions() - .unwrap() - .with_platform_verifier() - .with_no_client_auth(); +pub(crate) fn get_transport(validate_certificates: bool) -> Client, BoxBody> { + let tls_config = yaak_http::tls::get_config(validate_certificates); let mut http = HttpConnector::new(); http.enforce_http(false); let connector = - HttpsConnectorBuilder::new().with_tls_config(config).https_or_http().enable_http2().build(); + HttpsConnectorBuilder::new().with_tls_config(tls_config).https_or_http().enable_http2().build(); let client = Client::builder(TokioExecutor::new()) .pool_max_idle_per_host(0) diff --git a/src-tauri/yaak-http/Cargo.toml b/src-tauri/yaak-http/Cargo.toml index 40a6a2bc2..78455a519 100644 --- a/src-tauri/yaak-http/Cargo.toml +++ b/src-tauri/yaak-http/Cargo.toml @@ -7,4 +7,6 @@ publish = false [dependencies] yaak-models = { workspace = true } regex = "1.11.0" +rustls = { workspace = true, default-features = false, features = ["ring"] } +rustls-platform-verifier = { workspace = true } urlencoding = "2.1.3" diff --git a/src-tauri/yaak-http/src/lib.rs b/src-tauri/yaak-http/src/lib.rs index ccb746377..156046d91 100644 --- a/src-tauri/yaak-http/src/lib.rs +++ b/src-tauri/yaak-http/src/lib.rs @@ -1,3 +1,5 @@ +pub mod tls; + use yaak_models::models::HttpUrlParameter; pub fn apply_path_placeholders( diff --git a/src-tauri/yaak-http/src/tls.rs b/src-tauri/yaak-http/src/tls.rs new file mode 100644 index 000000000..b5fdd300a --- /dev/null +++ b/src-tauri/yaak-http/src/tls.rs @@ -0,0 +1,77 @@ +use std::sync::Arc; +use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}; +use rustls::{ClientConfig, DigitallySignedStruct, SignatureScheme}; +use rustls::crypto::ring; +use rustls::pki_types::{CertificateDer, ServerName, UnixTime}; +use rustls_platform_verifier::BuilderVerifierExt; + +pub fn get_config(validate_certificates: bool) -> ClientConfig { + let arc_crypto_provider = Arc::new(ring::default_provider()); + let config_builder = ClientConfig::builder_with_provider(arc_crypto_provider) + .with_safe_default_protocol_versions() + .unwrap(); + if validate_certificates { + // Use platform-native verifier to validate certificates + config_builder + .with_platform_verifier() + .with_no_client_auth() + } else { + config_builder + .dangerous() + .with_custom_certificate_verifier(Arc::new(NoVerifier)) + .with_no_client_auth() + } +} + +// Copied from reqwest: https://github.com/seanmonstar/reqwest/blob/595c80b1fbcdab73ac2ae93e4edc3406f453df25/src/tls.rs#L608 +#[derive(Debug)] +struct NoVerifier; + +impl ServerCertVerifier for NoVerifier { + fn verify_server_cert( + &self, + _end_entity: &CertificateDer, + _intermediates: &[CertificateDer], + _server_name: &ServerName, + _ocsp_response: &[u8], + _now: UnixTime, + ) -> Result { + Ok(ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &CertificateDer, + _dss: &DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _message: &[u8], + _cert: &CertificateDer, + _dss: &DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn supported_verify_schemes(&self) -> Vec { + vec![ + SignatureScheme::RSA_PKCS1_SHA1, + SignatureScheme::ECDSA_SHA1_Legacy, + SignatureScheme::RSA_PKCS1_SHA256, + SignatureScheme::ECDSA_NISTP256_SHA256, + SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::ECDSA_NISTP384_SHA384, + SignatureScheme::RSA_PKCS1_SHA512, + SignatureScheme::ECDSA_NISTP521_SHA512, + SignatureScheme::RSA_PSS_SHA256, + SignatureScheme::RSA_PSS_SHA384, + SignatureScheme::RSA_PSS_SHA512, + SignatureScheme::ED25519, + SignatureScheme::ED448, + ] + } +} diff --git a/src-tauri/yaak-ws/Cargo.toml b/src-tauri/yaak-ws/Cargo.toml index 8b7863216..0501c742a 100644 --- a/src-tauri/yaak-ws/Cargo.toml +++ b/src-tauri/yaak-ws/Cargo.toml @@ -9,8 +9,6 @@ publish = false futures-util = "0.3.31" log = "0.4.20" md5 = "0.7.0" -rustls = { version = "0.23.25", default-features = false, features = ["custom-provider", "ring"] } -rustls-platform-verifier = "0.5.1" serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } tauri = { workspace = true } diff --git a/src-tauri/yaak-ws/src/commands.rs b/src-tauri/yaak-ws/src/commands.rs index a1fe1c355..7230ac8b5 100644 --- a/src-tauri/yaak-ws/src/commands.rs +++ b/src-tauri/yaak-ws/src/commands.rs @@ -196,6 +196,7 @@ pub(crate) async fn connect( }; let base_environment = app_handle.db().get_base_environment(&unrendered_request.workspace_id)?; + let workspace = app_handle.db().get_workspace(&unrendered_request.workspace_id)?; let resolved_request = resolve_websocket_request(&window, &unrendered_request)?; let request = render_websocket_request( &resolved_request, @@ -298,7 +299,13 @@ pub(crate) async fn connect( } } - let response = match ws_manager.connect(&connection.id, url.as_str(), headers, receive_tx).await + let response = match ws_manager.connect( + &connection.id, + url.as_str(), + headers, + receive_tx, + workspace.setting_validate_certificates, + ).await { Ok(r) => r, Err(e) => { diff --git a/src-tauri/yaak-ws/src/connect.rs b/src-tauri/yaak-ws/src/connect.rs index f2853ff9e..2aa281c1d 100644 --- a/src-tauri/yaak-ws/src/connect.rs +++ b/src-tauri/yaak-ws/src/connect.rs @@ -1,7 +1,4 @@ use log::info; -use rustls::crypto::ring; -use rustls::ClientConfig; -use rustls_platform_verifier::BuilderVerifierExt; use std::sync::Arc; use tauri::http::HeaderMap; use tokio::net::TcpStream; @@ -16,14 +13,10 @@ use tokio_tungstenite::{ pub(crate) async fn ws_connect( url: &str, headers: HeaderMap, + validate_certificates: bool, ) -> crate::error::Result<(WebSocketStream>, Response)> { info!("Connecting to WS {url}"); - let arc_crypto_provider = Arc::new(ring::default_provider()); - let config = ClientConfig::builder_with_provider(arc_crypto_provider) - .with_safe_default_protocol_versions() - .unwrap() - .with_platform_verifier() - .with_no_client_auth(); + let tls_config = yaak_http::tls::get_config(validate_certificates); let mut req = url.into_client_request()?; let req_headers = req.headers_mut(); @@ -37,7 +30,7 @@ pub(crate) async fn ws_connect( req, Some(WebSocketConfig::default()), false, - Some(Connector::Rustls(Arc::new(config))), + Some(Connector::Rustls(Arc::new(tls_config))), ) .await?; Ok((stream, response)) diff --git a/src-tauri/yaak-ws/src/manager.rs b/src-tauri/yaak-ws/src/manager.rs index 1bc1fe758..530109c8f 100644 --- a/src-tauri/yaak-ws/src/manager.rs +++ b/src-tauri/yaak-ws/src/manager.rs @@ -31,12 +31,13 @@ impl WebsocketManager { url: &str, headers: HeaderMap, receive_tx: mpsc::Sender, + validate_certificates: bool, ) -> Result { let connections = self.connections.clone(); let connection_id = id.to_string(); let tx = receive_tx.clone(); - let (stream, response) = ws_connect(url, headers).await?; + let (stream, response) = ws_connect(url, headers, validate_certificates).await?; let (write, mut read) = stream.split(); connections.lock().await.insert(id.to_string(), write); From 79362c81e592c825d66a8484374d7ebb8690f6a3 Mon Sep 17 00:00:00 2001 From: James Cleverley-Prance Date: Thu, 29 May 2025 15:06:24 +0100 Subject: [PATCH 229/996] fix: oauth2 audience not sent (#10) --- plugins/auth-oauth2/src/getAccessToken.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth-oauth2/src/getAccessToken.ts b/plugins/auth-oauth2/src/getAccessToken.ts index 1129508a5..5651c8cbe 100644 --- a/plugins/auth-oauth2/src/getAccessToken.ts +++ b/plugins/auth-oauth2/src/getAccessToken.ts @@ -41,7 +41,7 @@ export async function getAccessToken( }; if (scope) httpRequest.body!.form.push({ name: 'scope', value: scope }); - if (scope) httpRequest.body!.form.push({ name: 'audience', value: audience }); + if (audience) httpRequest.body!.form.push({ name: 'audience', value: audience }); if (credentialsInBody) { httpRequest.body!.form.push({ name: 'client_id', value: clientId }); From 385a3696991d3f30d88f953fc8f58c39cc45525b Mon Sep 17 00:00:00 2001 From: "John D. Chancey" <139152739+chanceycode@users.noreply.github.com> Date: Thu, 29 May 2025 10:07:59 -0400 Subject: [PATCH 230/996] Fix: Add yaakcli to dev dependencies (#9) --- package-lock.json | 74 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index bfb1d1b47..68efc0051 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ }, "devDependencies": { "@types/node": "^22.7.4", + "@yaakapp/cli": "^0.1.5", "jsonpath": "^1.1.1", "typescript": "^5.6.2", "vitest": "^2.0.4", @@ -1022,6 +1023,79 @@ "resolved": "plugins/auth-oauth2", "link": true }, + "node_modules/@yaakapp/cli": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.1.5.tgz", + "integrity": "sha512-nx9Z8FhVr8afNkeYSDKZJg0PaYlqKQK2f8zj6MykJeeafHdauJ6EuXWXCmAK6uYLjrIaZI0S63tbgFRBq4kqog==", + "dev": true, + "hasInstallScript": true, + "bin": { + "yaakcli": "bin/cli.js" + }, + "optionalDependencies": { + "@yaakapp/cli-darwin-arm64": "0.1.5", + "@yaakapp/cli-darwin-x64": "0.1.5", + "@yaakapp/cli-linux-arm64": "0.1.5", + "@yaakapp/cli-linux-x64": "0.1.5", + "@yaakapp/cli-win32-x64": "0.1.5" + } + }, + "node_modules/@yaakapp/cli-darwin-arm64": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.1.5.tgz", + "integrity": "sha512-P66dwLDx8YWw/A9f7NlnsvnAYBwB8uAYu5gu6/dLZLmYAJ/vZ7kPiHuq1d23g4vKcsXPnjx3Djh3E44ACysMWA==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-darwin-x64": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.1.5.tgz", + "integrity": "sha512-PrwGW9MVJkx1zO3pCdoQFoP2dyzoczHc/ZddFZ6tLEzJu3eg/rrsDkTZfLL/7h5egjGWZKmeG3osS9uFhBU68A==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@yaakapp/cli-linux-arm64": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-arm64/-/cli-linux-arm64-0.1.5.tgz", + "integrity": "sha512-Pz63GBO1ikVvTKCP5qSZYLZRcepFAd05+UDFnehWsb4c1OKDsFqOMauPzpMPsCkdqsegSUku0Jly2lDfqmW/ig==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-linux-x64": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.1.5.tgz", + "integrity": "sha512-YuVDWjVkPtm7JzsN8VQ9ZTKcEnS7FnJ00wdaWh7IbgoBong/l2eb9Bhfv7A9Fm33VuHnS9QhlBvDGUazmnV3Mg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yaakapp/cli-win32-x64": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.1.5.tgz", + "integrity": "sha512-w8Oo8/tI/T8cat+tZSqk4OoQZuf1epoC5LR7iuIOOPYGrdxEO2kMDe2LZiG3vnE96Zbprvk3zbdBSrVU9y3wSA==", + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@yaakapp/exporter-curl": { "resolved": "plugins/exporter-curl", "link": true diff --git a/package.json b/package.json index a0da177c2..33edba009 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "jsonpath": "^1.1.1", "typescript": "^5.6.2", "vitest": "^2.0.4", - "workspaces-run": "^1.0.2" + "workspaces-run": "^1.0.2", + "@yaakapp/cli": "^0.1.5" }, "dependencies": { "@yaakapp/api": "^0.6.0" From 723e8d28748886741b5d535ac1373281b5ab7c7f Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 29 May 2025 07:16:39 -0700 Subject: [PATCH 231/996] Move everything into subdir for repo merge --- .idea/codeStyles/Project.xml | 121 +++ .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/jsLibraryMappings.xml | 6 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/plugins.iml | 25 + .idea/vcs.xml | 6 + .idea/workspace.xml | 736 ++++++++++++++++++ .../plugins/.github}/workflows/ci.yaml | 0 .gitignore => packages/plugins/.gitignore | 0 .../plugins/.prettierrc.json | 0 LICENSE => packages/plugins/LICENSE | 0 README.md => packages/plugins/README.md | 0 .../plugins/package-lock.json | 0 package.json => packages/plugins/package.json | 0 .../plugins/plugins}/auth-basic/package.json | 0 .../plugins/plugins}/auth-basic/src/index.ts | 0 .../plugins/plugins}/auth-bearer/package.json | 0 .../plugins/plugins}/auth-bearer/src/index.ts | 0 .../plugins/plugins}/auth-jwt/package.json | 0 .../plugins/plugins}/auth-jwt/src/index.ts | 0 .../plugins/plugins}/auth-oauth2/package.json | 0 .../auth-oauth2/src/getAccessToken.ts | 0 .../src/getOrRefreshAccessToken.ts | 0 .../src/grants/authorizationCode.ts | 0 .../src/grants/clientCredentials.ts | 0 .../auth-oauth2/src/grants/implicit.ts | 0 .../auth-oauth2/src/grants/password.ts | 0 .../plugins/plugins}/auth-oauth2/src/index.ts | 0 .../plugins/plugins}/auth-oauth2/src/store.ts | 0 .../plugins}/exporter-curl/package.json | 0 .../plugins}/exporter-curl/src/index.ts | 0 .../exporter-curl/tests/index.test.ts | 0 .../plugins}/filter-jsonpath/package.json | 0 .../plugins}/filter-jsonpath/src/index.ts | 0 .../plugins}/filter-xpath/package.json | 0 .../plugins}/filter-xpath/src/index.ts | 0 .../plugins}/importer-curl/package.json | 0 .../plugins}/importer-curl/src/index.ts | 0 .../importer-curl/tests/index.test.ts | 0 .../plugins}/importer-insomnia/package.json | 0 .../plugins}/importer-insomnia/src/common.ts | 0 .../plugins}/importer-insomnia/src/index.ts | 0 .../plugins}/importer-insomnia/src/v4.ts | 0 .../plugins}/importer-insomnia/src/v5.ts | 0 .../tests/fixtures/basic.input.json | 0 .../tests/fixtures/basic.output.json | 0 .../fixtures/version-5-minimal.input.yaml | 0 .../fixtures/version-5-minimal.output.json | 0 .../tests/fixtures/version-5.input.yaml | 0 .../tests/fixtures/version-5.output.json | 0 .../importer-insomnia/tests/index.test.ts | 0 .../plugins}/importer-openapi/package.json | 0 .../plugins}/importer-openapi/src/index.ts | 0 .../tests/fixtures/petstore.yaml | 0 .../importer-openapi/tests/index.test.ts | 0 .../plugins}/importer-postman/package.json | 0 .../plugins}/importer-postman/src/index.ts | 0 .../tests/fixtures/nested.input.json | 0 .../tests/fixtures/nested.output.json | 0 .../tests/fixtures/params.input.json | 0 .../tests/fixtures/params.output.json | 0 .../importer-postman/tests/index.test.ts | 0 .../plugins}/importer-yaak/package.json | 0 .../plugins}/importer-yaak/src/index.ts | 0 .../importer-yaak/tests/index.test.ts | 0 .../template-function-cookie/package.json | 0 .../template-function-cookie/src/index.ts | 0 .../template-function-encode/package.json | 0 .../template-function-encode/src/index.ts | 0 .../template-function-fs/package.json | 0 .../template-function-fs/src/index.ts | 0 .../template-function-hash/package.json | 0 .../template-function-hash/src/index.ts | 0 .../template-function-json/package.json | 0 .../template-function-json/src/index.ts | 0 .../template-function-prompt/package.json | 0 .../template-function-prompt/src/index.ts | 0 .../template-function-regex/package.json | 0 .../template-function-regex/src/index.ts | 0 .../template-function-request/package.json | 0 .../template-function-request/src/index.ts | 0 .../template-function-response/package.json | 0 .../template-function-response/src/index.ts | 0 .../template-function-uuid/package.json | 0 .../template-function-uuid/src/index.ts | 0 .../template-function-xml/package.json | 0 .../template-function-xml/src/index.ts | 0 .../plugins/tsconfig.json | 0 90 files changed, 919 insertions(+) create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/jsLibraryMappings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/plugins.iml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml rename {.github => packages/plugins/.github}/workflows/ci.yaml (100%) rename .gitignore => packages/plugins/.gitignore (100%) rename .prettierrc.json => packages/plugins/.prettierrc.json (100%) rename LICENSE => packages/plugins/LICENSE (100%) rename README.md => packages/plugins/README.md (100%) rename package-lock.json => packages/plugins/package-lock.json (100%) rename package.json => packages/plugins/package.json (100%) rename {plugins => packages/plugins/plugins}/auth-basic/package.json (100%) rename {plugins => packages/plugins/plugins}/auth-basic/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/auth-bearer/package.json (100%) rename {plugins => packages/plugins/plugins}/auth-bearer/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/auth-jwt/package.json (100%) rename {plugins => packages/plugins/plugins}/auth-jwt/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/auth-oauth2/package.json (100%) rename {plugins => packages/plugins/plugins}/auth-oauth2/src/getAccessToken.ts (100%) rename {plugins => packages/plugins/plugins}/auth-oauth2/src/getOrRefreshAccessToken.ts (100%) rename {plugins => packages/plugins/plugins}/auth-oauth2/src/grants/authorizationCode.ts (100%) rename {plugins => packages/plugins/plugins}/auth-oauth2/src/grants/clientCredentials.ts (100%) rename {plugins => packages/plugins/plugins}/auth-oauth2/src/grants/implicit.ts (100%) rename {plugins => packages/plugins/plugins}/auth-oauth2/src/grants/password.ts (100%) rename {plugins => packages/plugins/plugins}/auth-oauth2/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/auth-oauth2/src/store.ts (100%) rename {plugins => packages/plugins/plugins}/exporter-curl/package.json (100%) rename {plugins => packages/plugins/plugins}/exporter-curl/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/exporter-curl/tests/index.test.ts (100%) rename {plugins => packages/plugins/plugins}/filter-jsonpath/package.json (100%) rename {plugins => packages/plugins/plugins}/filter-jsonpath/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/filter-xpath/package.json (100%) rename {plugins => packages/plugins/plugins}/filter-xpath/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/importer-curl/package.json (100%) rename {plugins => packages/plugins/plugins}/importer-curl/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/importer-curl/tests/index.test.ts (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/package.json (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/src/common.ts (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/src/v4.ts (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/src/v5.ts (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/tests/fixtures/basic.input.json (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/tests/fixtures/basic.output.json (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/tests/fixtures/version-5-minimal.input.yaml (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/tests/fixtures/version-5-minimal.output.json (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/tests/fixtures/version-5.input.yaml (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/tests/fixtures/version-5.output.json (100%) rename {plugins => packages/plugins/plugins}/importer-insomnia/tests/index.test.ts (100%) rename {plugins => packages/plugins/plugins}/importer-openapi/package.json (100%) rename {plugins => packages/plugins/plugins}/importer-openapi/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/importer-openapi/tests/fixtures/petstore.yaml (100%) rename {plugins => packages/plugins/plugins}/importer-openapi/tests/index.test.ts (100%) rename {plugins => packages/plugins/plugins}/importer-postman/package.json (100%) rename {plugins => packages/plugins/plugins}/importer-postman/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/importer-postman/tests/fixtures/nested.input.json (100%) rename {plugins => packages/plugins/plugins}/importer-postman/tests/fixtures/nested.output.json (100%) rename {plugins => packages/plugins/plugins}/importer-postman/tests/fixtures/params.input.json (100%) rename {plugins => packages/plugins/plugins}/importer-postman/tests/fixtures/params.output.json (100%) rename {plugins => packages/plugins/plugins}/importer-postman/tests/index.test.ts (100%) rename {plugins => packages/plugins/plugins}/importer-yaak/package.json (100%) rename {plugins => packages/plugins/plugins}/importer-yaak/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/importer-yaak/tests/index.test.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-cookie/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-cookie/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-encode/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-encode/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-fs/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-fs/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-hash/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-hash/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-json/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-json/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-prompt/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-prompt/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-regex/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-regex/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-request/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-request/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-response/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-response/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-uuid/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-uuid/src/index.ts (100%) rename {plugins => packages/plugins/plugins}/template-function-xml/package.json (100%) rename {plugins => packages/plugins/plugins}/template-function-xml/src/index.ts (100%) rename tsconfig.json => packages/plugins/tsconfig.json (100%) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 000000000..7fff17eee --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 000000000..79ee123c2 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 000000000..c88ef5f1b --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 000000000..cc3da93f8 --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 000000000..639900d13 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 000000000..9aabe3f91 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/plugins.iml b/.idea/plugins.iml new file mode 100644 index 000000000..329b52180 --- /dev/null +++ b/.idea/plugins.iml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..35eb1ddfb --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 000000000..d1c0d4fd4 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,736 @@ + + + + + + + + + + + + + + { + "lastFilter": { + "state": "OPEN", + "assignee": "gschier" + } +} + { + "selectedUrlAndAccountId": { + "url": "git@github.com:yaakapp/plugins.git", + "accountId": "71967edb-f3a0-49b0-a8bb-91c112bf4a62" + } +} + {} + { + "isMigrated": true +} + + + + + { + "associatedIndex": 0 +} + + + + + + + build.executor": "Run", + "npm.auth-jwt > dev.executor": "Debug", + "npm.auth-none > build.executor": "Run", + "npm.auth-oauth2 > dev.executor": "Run", + "npm.build (1).executor": "Run", + "npm.build (2).executor": "Run", + "npm.build.executor": "Run", + "npm.dev.executor": "Run", + "npm.exporter-curl > build.executor": "Run", + "npm.exporter-curl > dev.executor": "Run", + "npm.exporter-curl > watch.executor": "Run", + "npm.importer-openapi > dev.executor": "Run", + "npm.template-function-secure > dev.executor": "Run", + "org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "", + "org.rust.first.attach.projects": "true", + "settings.editor.selected.configurable": "preferences.pluginManager", + "ts.external.directory.path": "/Users/gschier/Applications/IntelliJ IDEA Ultimate.app/Contents/plugins/javascript-plugin/jsLanguageServicesImpl/external", + "typescript.add.unambiguous.imports.on.the.fly": "true" + }, + "keyToStringList": { + "com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File": [ + "TypeScript", + "TEXT", + "JSON" + ] + } +}]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src-web/main.css b/src-web/main.css index 12bb477fd..d4b8a00d8 100644 --- a/src-web/main.css +++ b/src-web/main.css @@ -9,6 +9,12 @@ @apply w-full h-full overflow-hidden text-text bg-surface; } + :root { + /* Must default these variables or the default will break */ + --font-family-interface: ''; + --font-family-editor: ''; + } + /* Never show ligatures */ :root { font-variant-ligatures: none; diff --git a/src-web/routes/__root.tsx b/src-web/routes/__root.tsx index 7b4b7f7f9..4769359b0 100644 --- a/src-web/routes/__root.tsx +++ b/src-web/routes/__root.tsx @@ -1,5 +1,6 @@ import { QueryClientProvider } from '@tanstack/react-query'; import { createRootRoute, Outlet } from '@tanstack/react-router'; +import { type } from '@tauri-apps/plugin-os'; import classNames from 'classnames'; import { Provider as JotaiProvider } from 'jotai'; import { domAnimation, LazyMotion, MotionConfig } from 'motion/react'; @@ -13,7 +14,6 @@ import RouteError from '../components/RouteError'; import { Toasts } from '../components/Toasts'; import { jotaiStore } from '../lib/jotai'; import { queryClient } from '../lib/queryClient'; -import { type } from '@tauri-apps/plugin-os'; export const Route = createRootRoute({ component: RouteComponent, @@ -32,14 +32,7 @@ function RouteComponent() { -
- -
+ @@ -49,3 +42,13 @@ function RouteComponent() { ); } + +function Layout() { + return ( +
+ +
+ ); +} diff --git a/src-web/tailwind.config.cjs b/src-web/tailwind.config.cjs index ca48e2658..173a58185 100644 --- a/src-web/tailwind.config.cjs +++ b/src-web/tailwind.config.cjs @@ -7,7 +7,7 @@ const sizes = { md: '2.3rem', }; -/** @type {import("tailwindcss").Config} */ +/** @type {import('tailwindcss').Config} */ module.exports = { darkMode: ['class', '[data-resolved-appearance="dark"]'], content: [ @@ -43,6 +43,7 @@ module.exports = { }, fontFamily: { mono: [ + 'var(--font-family-editor)', 'JetBrains Mono', 'ui-monospace', 'SFMono-Regular', @@ -58,6 +59,7 @@ module.exports = { 'monospace', ], sans: [ + 'var(--font-family-interface)', 'Inter UI', '-apple-system', 'BlinkMacSystemFont', From 648a1ac53c0f0a4c13543a46a43423107a781416 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 8 Jun 2025 22:49:43 -0700 Subject: [PATCH 270/996] Update DEVELOPMENT.md --- DEVELOPMENT.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 8faa16d92..961623896 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -50,11 +50,9 @@ New migrations can be created from the `src-tauri/` directory: npm run migration ``` -Run the app to apply the migrations. +Rerun the app to apply the migrations. -If nothing happens, try `cargo clean` and run the app again. - -_Note: Development builds use a separate database location from production builds._ +_Note: For safety, development builds use a separate database location from production builds._ ## Lezer Grammer Generation From be0a8fc27a8a79fbad28271720ca0b70dd535a95 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Jun 2025 14:29:12 -0700 Subject: [PATCH 271/996] Add proxy bypass setting and rewrite proxy logic --- src-tauri/src/http_request.rs | 48 ++++++++++++------- src-tauri/yaak-models/bindings/gen_models.ts | 2 +- src-tauri/yaak-models/src/models.rs | 9 ++-- src-web/components/Settings/SettingsProxy.tsx | 41 ++++++++++++++-- 4 files changed, 74 insertions(+), 26 deletions(-) diff --git a/src-tauri/src/http_request.rs b/src-tauri/src/http_request.rs index 97597d595..a43ba29de 100644 --- a/src-tauri/src/http_request.rs +++ b/src-tauri/src/http_request.rs @@ -7,7 +7,7 @@ use http::{HeaderMap, HeaderName, HeaderValue}; use log::{debug, error, warn}; use mime_guess::Mime; use reqwest::redirect::Policy; -use reqwest::{Method, Response}; +use reqwest::{Method, NoProxy, Response}; use reqwest::{Proxy, Url, multipart}; use serde_json::Value; use std::collections::BTreeMap; @@ -120,25 +120,39 @@ pub async fn send_http_request( https, auth, disabled, + bypass, }) if !disabled => { - debug!("Using proxy http={http} https={https}"); - let mut proxy = Proxy::custom(move |url| { - let http = if http.is_empty() { None } else { Some(http.to_owned()) }; - let https = if https.is_empty() { None } else { Some(https.to_owned()) }; - let proxy_url = match (url.scheme(), http, https) { - ("http", Some(proxy_url), _) => Some(proxy_url), - ("https", _, Some(proxy_url)) => Some(proxy_url), - _ => None, + debug!("Using proxy http={http} https={https} bypass={bypass}"); + if !http.is_empty() { + match Proxy::http(http) { + Ok(mut proxy) => { + if let Some(ProxySettingAuth { user, password }) = auth.clone() { + debug!("Using http proxy auth"); + proxy = proxy.basic_auth(user.as_str(), password.as_str()); + } + proxy = proxy.no_proxy(NoProxy::from_string(&bypass)); + client_builder = client_builder.proxy(proxy); + } + Err(e) => { + warn!("Failed to apply http proxy {e:?}"); + } + }; + } + if !https.is_empty() { + match Proxy::https(https) { + Ok(mut proxy) => { + if let Some(ProxySettingAuth { user, password }) = auth { + debug!("Using https proxy auth"); + proxy = proxy.basic_auth(user.as_str(), password.as_str()); + } + proxy = proxy.no_proxy(NoProxy::from_string(&bypass)); + client_builder = client_builder.proxy(proxy); + } + Err(e) => { + warn!("Failed to apply https proxy {e:?}"); + } }; - proxy_url - }); - - if let Some(ProxySettingAuth { user, password }) = auth { - debug!("Using proxy auth"); - proxy = proxy.basic_auth(user.as_str(), password.as_str()); } - - client_builder = client_builder.proxy(proxy); } _ => {} // Nothing to do for this one, as it is the default } diff --git a/src-tauri/yaak-models/bindings/gen_models.ts b/src-tauri/yaak-models/bindings/gen_models.ts index 9e6c95cf3..7da8e425a 100644 --- a/src-tauri/yaak-models/bindings/gen_models.ts +++ b/src-tauri/yaak-models/bindings/gen_models.ts @@ -58,7 +58,7 @@ export type Plugin = { model: "plugin", id: string, createdAt: string, updatedAt export type PluginKeyValue = { model: "plugin_key_value", createdAt: string, updatedAt: string, pluginName: string, key: string, value: string, }; -export type ProxySetting = { "type": "enabled", disabled: boolean, http: string, https: string, auth: ProxySettingAuth | null, } | { "type": "disabled" }; +export type ProxySetting = { "type": "enabled", disabled: boolean, http: string, https: string, auth: ProxySettingAuth | null, bypass: string, } | { "type": "disabled" }; export type ProxySettingAuth = { user: string, password: string, }; diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index 2750f5689..4581646e7 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -31,12 +31,15 @@ macro_rules! impl_model { #[ts(export, export_to = "gen_models.ts")] pub enum ProxySetting { Enabled { - #[serde(default)] - // This was added after on so give it a default to be able to deserialize older values - disabled: bool, http: String, https: String, auth: Option, + + // These were added later, so give them defaults + #[serde(default)] + bypass: String, + #[serde(default)] + disabled: bool, }, Disabled, } diff --git a/src-web/components/Settings/SettingsProxy.tsx b/src-web/components/Settings/SettingsProxy.tsx index c2094f407..a315831dd 100644 --- a/src-web/components/Settings/SettingsProxy.tsx +++ b/src-web/components/Settings/SettingsProxy.tsx @@ -30,6 +30,7 @@ export function SettingsProxy() { http: '', https: '', auth: { user: '', password: '' }, + bypass: '', }, }); } else { @@ -53,10 +54,11 @@ export function SettingsProxy() { const { proxy } = settings; const http = proxy?.type === 'enabled' ? proxy.http : ''; const https = proxy?.type === 'enabled' ? proxy.https : ''; + const bypass = proxy?.type === 'enabled' ? proxy.bypass : ''; const auth = proxy?.type === 'enabled' ? proxy.auth : null; const disabled = !enabled; await patchModel(settings, { - proxy: { type: 'enabled', http, https, auth, disabled }, + proxy: { type: 'enabled', http, https, auth, disabled, bypass }, }); }} /> @@ -73,6 +75,7 @@ export function SettingsProxy() { onChange={async (http) => { const { proxy } = settings; const https = proxy?.type === 'enabled' ? proxy.https : ''; + const bypass = proxy?.type === 'enabled' ? proxy.bypass : ''; const auth = proxy?.type === 'enabled' ? proxy.auth : null; const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; await patchModel(settings, { @@ -82,6 +85,7 @@ export function SettingsProxy() { https, auth, disabled, + bypass, }, }); }} @@ -98,10 +102,11 @@ export function SettingsProxy() { onChange={async (https) => { const { proxy } = settings; const http = proxy?.type === 'enabled' ? proxy.http : ''; + const bypass = proxy?.type === 'enabled' ? proxy.bypass : ''; const auth = proxy?.type === 'enabled' ? proxy.auth : null; const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; await patchModel(settings, { - proxy: { type: 'enabled', http, https, auth, disabled }, + proxy: { type: 'enabled', http, https, auth, disabled, bypass }, }); }} /> @@ -115,9 +120,10 @@ export function SettingsProxy() { const http = proxy?.type === 'enabled' ? proxy.http : ''; const https = proxy?.type === 'enabled' ? proxy.https : ''; const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; + const bypass = proxy?.type === 'enabled' ? proxy.bypass : ''; const auth = enabled ? { user: '', password: '' } : null; await patchModel(settings, { - proxy: { type: 'enabled', http, https, auth, disabled }, + proxy: { type: 'enabled', http, https, auth, disabled, bypass }, }); }} /> @@ -135,10 +141,11 @@ export function SettingsProxy() { const http = proxy?.type === 'enabled' ? proxy.http : ''; const https = proxy?.type === 'enabled' ? proxy.https : ''; const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; + const bypass = proxy?.type === 'enabled' ? proxy.bypass : ''; const password = proxy?.type === 'enabled' ? (proxy.auth?.password ?? '') : ''; const auth = { user, password }; await patchModel(settings, { - proxy: { type: 'enabled', http, https, auth, disabled }, + proxy: { type: 'enabled', http, https, auth, disabled, bypass }, }); }} /> @@ -153,15 +160,39 @@ export function SettingsProxy() { const http = proxy?.type === 'enabled' ? proxy.http : ''; const https = proxy?.type === 'enabled' ? proxy.https : ''; const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; + const bypass = proxy?.type === 'enabled' ? proxy.bypass : ''; const user = proxy?.type === 'enabled' ? (proxy.auth?.user ?? '') : ''; const auth = { user, password }; await patchModel(settings, { - proxy: { type: 'enabled', http, https, auth, disabled }, + proxy: { type: 'enabled', http, https, auth, disabled, bypass }, }); }} /> )} + {settings.proxy.type === 'enabled' && ( + <> + + { + const { proxy } = settings; + const http = proxy?.type === 'enabled' ? proxy.http : ''; + const https = proxy?.type === 'enabled' ? proxy.https : ''; + const disabled = proxy?.type === 'enabled' ? proxy.disabled : false; + const user = proxy?.type === 'enabled' ? (proxy.auth?.user ?? '') : ''; + const password = proxy?.type === 'enabled' ? (proxy.auth?.password ?? '') : ''; + const auth = { user, password }; + await patchModel(settings, { + proxy: { type: 'enabled', http, https, auth, disabled, bypass }, + }); + }} + /> + + )}
)} From 383fd05c6cc6c8c5740856ed5d9b8bd8dec24f04 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 9 Jun 2025 21:19:44 -0700 Subject: [PATCH 272/996] Split appearance settings into theme/interface --- src-web/components/Settings/Settings.tsx | 15 +- .../components/Settings/SettingsInterface.tsx | 137 ++++++++++++++++++ ...ttingsAppearance.tsx => SettingsTheme.tsx} | 124 +--------------- 3 files changed, 148 insertions(+), 128 deletions(-) create mode 100644 src-web/components/Settings/SettingsInterface.tsx rename src-web/components/Settings/{SettingsAppearance.tsx => SettingsTheme.tsx} (53%) diff --git a/src-web/components/Settings/Settings.tsx b/src-web/components/Settings/Settings.tsx index 21d1888ce..1629b68a7 100644 --- a/src-web/components/Settings/Settings.tsx +++ b/src-web/components/Settings/Settings.tsx @@ -8,22 +8,24 @@ import { capitalize } from '../../lib/capitalize'; import { HStack } from '../core/Stacks'; import { TabContent, Tabs } from '../core/Tabs/Tabs'; import { HeaderSize } from '../HeaderSize'; -import { SettingsAppearance } from './SettingsAppearance'; +import { SettingsInterface } from './SettingsInterface'; import { SettingsGeneral } from './SettingsGeneral'; import { SettingsLicense } from './SettingsLicense'; import { SettingsPlugins } from './SettingsPlugins'; import { SettingsProxy } from './SettingsProxy'; +import { SettingsTheme } from './SettingsTheme'; interface Props { hide?: () => void; } const TAB_GENERAL = 'general'; -const TAB_APPEARANCE = 'appearance'; +const TAB_INTERFACE = 'interface'; +const TAB_THEME = 'theme'; const TAB_PROXY = 'proxy'; const TAB_PLUGINS = 'plugins'; const TAB_LICENSE = 'license'; -const tabs = [TAB_GENERAL, TAB_APPEARANCE, TAB_PROXY, TAB_PLUGINS, TAB_LICENSE] as const; +const tabs = [TAB_GENERAL, TAB_THEME, TAB_INTERFACE, TAB_PROXY, TAB_PLUGINS, TAB_LICENSE] as const; export type SettingsTab = (typeof tabs)[number]; export default function Settings({ hide }: Props) { @@ -73,8 +75,11 @@ export default function Settings({ hide }: Props) { - - + + + + + diff --git a/src-web/components/Settings/SettingsInterface.tsx b/src-web/components/Settings/SettingsInterface.tsx new file mode 100644 index 000000000..feacb6607 --- /dev/null +++ b/src-web/components/Settings/SettingsInterface.tsx @@ -0,0 +1,137 @@ +import { type } from '@tauri-apps/plugin-os'; +import { useFonts } from '@yaakapp-internal/fonts'; +import type { EditorKeymap } from '@yaakapp-internal/models'; +import { patchModel, settingsAtom } from '@yaakapp-internal/models'; +import { useAtomValue } from 'jotai'; +import React from 'react'; +import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace'; +import { clamp } from '../../lib/clamp'; +import { Checkbox } from '../core/Checkbox'; +import { Icon } from '../core/Icon'; +import { Select } from '../core/Select'; +import { HStack, VStack } from '../core/Stacks'; + +const NULL_FONT_VALUE = '__NULL_FONT__'; + +const fontSizeOptions = [ + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, +].map((n) => ({ label: `${n}`, value: `${n}` })); + +const keymaps: { value: EditorKeymap; label: string }[] = [ + { value: 'default', label: 'Default' }, + { value: 'vim', label: 'Vim' }, + { value: 'vscode', label: 'VSCode' }, + { value: 'emacs', label: 'Emacs' }, +]; + +export function SettingsInterface() { + const workspace = useAtomValue(activeWorkspaceAtom); + const settings = useAtomValue(settingsAtom); + const fonts = useFonts(); + + if (settings == null || workspace == null) { + return null; + } + + return ( + + + {fonts.data && ( + patchModel(settings, { interfaceFontSize: parseInt(v) })} + /> + + + {fonts.data && ( + + patchModel(settings, { editorFontSize: clamp(parseInt(v) || 14, 8, 30) }) + } + /> + + ({ - label: f, - value: f, - })) ?? []), - // Some people like monospace fonts for the UI - ...(fonts.data.editorFonts.map((f) => ({ - label: f, - value: f, - })) ?? []), - ]} - onChange={async (v) => { - const interfaceFont = v === NULL_FONT_VALUE ? null : v; - await patchModel(settings, { interfaceFont }); - }} - /> - )} - ({ - label: f, - value: f, - })) ?? []), - ]} - onChange={async (v) => { - const editorFont = v === NULL_FONT_VALUE ? null : v; - await patchModel(settings, { editorFont }); - }} - /> - )} - } - size="sm" - name="editorKeymap" - label="Editor Keymap" - value={`${settings.editorKeymap}`} - options={keymaps} - onChange={(v) => patchModel(settings, { editorKeymap: v })} - /> -
- patchModel(settings, { editorSoftWrap })} - /> - patchModel(settings, { coloredMethods })} - /> -
- - {type() !== 'macos' && ( - patchModel(settings, { hideWindowControls })} - /> - )} - - - { + setSearchQuery(value); + } + } + onKeyDown={ + (e) => { + // check if enter + if (e.key === 'Enter' && viewMode !== 'search') { + addToHistory({ + schemaPointer: null, + viewMode: 'search', + }) + setViewMode('search'); + } + } + } + /> + + {/* End of search bar */} +
+ { renderView() } +
+ + ); +} + +export function GraphQLDocsExplorer() { + const graphqlSchema = useAtomValue(graphqlSchemaAtom); + + if (graphqlSchema) { + return ; + } + + return
There is no schema
; +} diff --git a/src-web/components/GraphQLEditor.tsx b/src-web/components/GraphQLEditor.tsx index 000c96a2a..2b762b5b0 100644 --- a/src-web/components/GraphQLEditor.tsx +++ b/src-web/components/GraphQLEditor.tsx @@ -16,6 +16,8 @@ import { Editor } from './core/Editor/Editor'; import { FormattedError } from './core/FormattedError'; import { Icon } from './core/Icon'; import { Separator } from './core/Separator'; +import { useAtom } from "jotai"; +import { graphqlDocStateAtom, graphqlSchemaAtom } from "../atoms/graphqlSchemaAtom"; type Props = Pick & { baseRequest: HttpRequest; @@ -45,6 +47,8 @@ export function GraphQLEditor({ request, onChange, baseRequest, ...extraEditorPr return { query: request.body.query ?? '', variables: request.body.variables ?? '' }; }, [extraEditorProps.forceUpdateKey]); + const [, setGraphqlSchemaAtomValue] = useAtom(graphqlSchemaAtom); + const [isDocOpen, setGraphqlDocStateAtomValue] = useAtom(graphqlDocStateAtom); const handleChangeQuery = (query: string) => { const newBody = { query, variables: currentBody.variables || undefined }; @@ -62,100 +66,121 @@ export function GraphQLEditor({ request, onChange, baseRequest, ...extraEditorPr useEffect(() => { if (editorViewRef.current == null) return; updateSchema(editorViewRef.current, schema ?? undefined); - }, [schema]); + setGraphqlSchemaAtomValue(schema); + }, [schema, setGraphqlSchemaAtomValue]); const actions = useMemo( () => [ -
- {schema === undefined ? null /* Initializing */ : ( - -

Schema introspection failed

- -
- - ), - }); - }} - > - View Error - - - ), - type: 'content', - }, - { - label: 'Refetch', - leftSlot: , - onSelect: refetch, - }, - { - label: 'Clear', - onSelect: clear, - hidden: !schema, - color: 'danger', - leftSlot: , - }, - { type: 'separator', label: 'Setting' }, - { - label: 'Automatic Introspection', - onSelect: () => { - setAutoIntrospectDisabled({ - ...autoIntrospectDisabled, - [baseRequest.id]: !autoIntrospectDisabled?.[baseRequest.id], - }); - }, - leftSlot: ( - - ), - }, - ]} - > +
+
+ { schema === undefined ? null /* Initializing */ : ( - - )} + ) } +
+
+ {schema === undefined ? null /* Initializing */ : ( + +

Schema introspection failed

+ +
+ + ), + }); + }} + > + View Error + + + ), + type: 'content', + }, + { + label: 'Refetch', + leftSlot: , + onSelect: refetch, + }, + { + label: 'Clear', + onSelect: clear, + hidden: !schema, + color: 'danger', + leftSlot: , + }, + { type: 'separator', label: 'Setting' }, + { + label: 'Automatic Introspection', + onSelect: () => { + setAutoIntrospectDisabled({ + ...autoIntrospectDisabled, + [baseRequest.id]: !autoIntrospectDisabled?.[baseRequest.id], + }); + }, + leftSlot: ( + + ), + }, + ]} + > + + + )} +
, ], [ @@ -167,6 +192,8 @@ export function GraphQLEditor({ request, onChange, baseRequest, ...extraEditorPr clear, schema, setAutoIntrospectDisabled, + isDocOpen, + setGraphqlDocStateAtomValue ], ); diff --git a/src-web/components/HttpRequestLayout.tsx b/src-web/components/HttpRequestLayout.tsx index 443677157..61a1d03cf 100644 --- a/src-web/components/HttpRequestLayout.tsx +++ b/src-web/components/HttpRequestLayout.tsx @@ -4,6 +4,11 @@ import type { HttpRequest } from '@yaakapp-internal/models'; import { SplitLayout } from './core/SplitLayout'; import { HttpRequestPane } from './HttpRequestPane'; import { HttpResponsePane } from './HttpResponsePane'; +import { GraphQLDocsExplorer } from "./GraphQLDocsExplorer"; +import { + useAtomValue +} from 'jotai'; +import { graphqlDocStateAtom } from "../atoms/graphqlSchemaAtom"; interface Props { activeRequest: HttpRequest; @@ -11,6 +16,11 @@ interface Props { } export function HttpRequestLayout({ activeRequest, style }: Props) { + const { + bodyType, + } = activeRequest; + const isDocOpen = useAtomValue(graphqlDocStateAtom); + return ( )} - secondSlot={({ style }) => } + secondSlot={ + bodyType === 'graphql' && isDocOpen + ? () => ( + + } + secondSlot={ + () => + } + /> + ) + : ( + ({ style }) => + ) + } /> ); } diff --git a/src-web/components/core/Icon.tsx b/src-web/components/core/Icon.tsx index c95c16605..626cc85cb 100644 --- a/src-web/components/core/Icon.tsx +++ b/src-web/components/core/Icon.tsx @@ -23,6 +23,7 @@ const icons = { arrow_up_from_line: lucide.ArrowUpFromLineIcon, badge_check: lucide.BadgeCheckIcon, box: lucide.BoxIcon, + book_open_text: lucide.BookOpenText, cake: lucide.CakeIcon, chat: lucide.MessageSquare, check: lucide.CheckIcon, From b5620fcdf351339c96a0e3be0e6ed76b6c249e54 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 22 Jun 2025 07:06:43 -0700 Subject: [PATCH 275/996] Merge pull request #227 * Search and install plugins PoC * Checksum * Tab sidebar for settings * Fix nested tabs, and tweaks * Table for plugin results * Deep links working * Focus window during deep links * Merge branch 'master' into plugin-directory * More stuff --- .../src/bindings/gen_events.ts | 2 +- .../src/bindings/gen_search.ts | 5 + packages/plugin-runtime/src/PluginInstance.ts | 22 +- src-tauri/Cargo.lock | 292 ++++++++++++++++-- src-tauri/Cargo.toml | 24 +- src-tauri/capabilities/capabilities.json | 3 +- src-tauri/macos/entitlements.plist | 4 - src-tauri/src/history.rs | 12 - src-tauri/src/import.rs | 105 +++++++ src-tauri/src/lib.rs | 127 ++------ src-tauri/src/notifications.rs | 3 +- src-tauri/src/plugin_events.rs | 4 +- src-tauri/src/uri_scheme.rs | 87 ++++-- src-tauri/tauri.conf.json | 1 - src-tauri/yaak-common/Cargo.toml | 3 + src-tauri/yaak-common/src/api_client.rs | 23 ++ src-tauri/yaak-common/src/error.rs | 19 ++ src-tauri/yaak-common/src/lib.rs | 5 +- src-tauri/yaak-common/src/platform.rs | 23 ++ src-tauri/yaak-crypto/Cargo.toml | 2 +- src-tauri/yaak-git/Cargo.toml | 2 +- src-tauri/yaak-license/Cargo.toml | 1 + src-tauri/yaak-license/src/lib.rs | 12 - src-tauri/yaak-license/src/license.rs | 7 +- src-tauri/yaak-models/Cargo.toml | 8 +- src-tauri/yaak-models/bindings/gen_models.ts | 2 +- src-tauri/yaak-plugins/Cargo.toml | 17 +- src-tauri/yaak-plugins/bindings/gen_events.ts | 2 +- src-tauri/yaak-plugins/bindings/gen_search.ts | 5 + src-tauri/yaak-plugins/build.rs | 5 + src-tauri/yaak-plugins/index.ts | 12 + .../yaak-plugins/permissions/default.toml | 3 + src-tauri/yaak-plugins/src/api.rs | 67 ++++ src-tauri/yaak-plugins/src/checksum.rs | 8 + src-tauri/yaak-plugins/src/commands.rs | 45 +++ src-tauri/yaak-plugins/src/error.rs | 27 +- src-tauri/yaak-plugins/src/events.rs | 2 +- src-tauri/yaak-plugins/src/install.rs | 60 ++++ src-tauri/yaak-plugins/src/lib.rs | 8 +- src-tauri/yaak-plugins/src/manager.rs | 44 ++- src-tauri/yaak-sync/Cargo.toml | 4 +- src-tauri/yaak-ws/Cargo.toml | 2 +- src-web/components/GrpcRequestPane.tsx | 2 +- src-web/components/HttpRequestPane.tsx | 2 +- src-web/components/HttpResponsePane.tsx | 2 +- src-web/components/ImportDataDialog.tsx | 1 + src-web/components/Settings/Settings.tsx | 4 +- .../components/Settings/SettingsPlugins.tsx | 255 +++++++++++---- src-web/components/SettingsDropdown.tsx | 5 +- src-web/components/WebsocketRequestPane.tsx | 2 +- src-web/components/Workspace.tsx | 13 +- src-web/components/core/Tabs/Tabs.tsx | 41 ++- src-web/hooks/useImportData.tsx | 109 ------- src-web/hooks/usePluginInfo.ts | 5 +- src-web/hooks/useUninstallPlugin.ts | 9 +- src-web/lib/importData.tsx | 107 +++++++ 56 files changed, 1222 insertions(+), 444 deletions(-) create mode 100644 packages/plugin-runtime-types/src/bindings/gen_search.ts create mode 100644 src-tauri/src/import.rs create mode 100644 src-tauri/yaak-common/src/api_client.rs create mode 100644 src-tauri/yaak-common/src/error.rs create mode 100644 src-tauri/yaak-common/src/platform.rs create mode 100644 src-tauri/yaak-plugins/bindings/gen_search.ts create mode 100644 src-tauri/yaak-plugins/build.rs create mode 100644 src-tauri/yaak-plugins/permissions/default.toml create mode 100644 src-tauri/yaak-plugins/src/api.rs create mode 100644 src-tauri/yaak-plugins/src/checksum.rs create mode 100644 src-tauri/yaak-plugins/src/commands.rs create mode 100644 src-tauri/yaak-plugins/src/install.rs delete mode 100644 src-web/hooks/useImportData.tsx create mode 100644 src-web/lib/importData.tsx diff --git a/packages/plugin-runtime-types/src/bindings/gen_events.ts b/packages/plugin-runtime-types/src/bindings/gen_events.ts index 1a82fb1be..001a58d03 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_events.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_events.ts @@ -372,7 +372,7 @@ export type ImportResponse = { resources: ImportResources, }; export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: PluginWindowContext, payload: InternalEventPayload, }; -export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "list_cookie_names_request" } & ListCookieNamesRequest | { "type": "list_cookie_names_response" } & ListCookieNamesResponse | { "type": "get_cookie_value_request" } & GetCookieValueRequest | { "type": "get_cookie_value_response" } & GetCookieValueResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; +export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & BootResponse | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "list_cookie_names_request" } & ListCookieNamesRequest | { "type": "list_cookie_names_response" } & ListCookieNamesResponse | { "type": "get_cookie_value_request" } & GetCookieValueRequest | { "type": "get_cookie_value_response" } & GetCookieValueResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; export type JsonPrimitive = string | number | boolean | null; diff --git a/packages/plugin-runtime-types/src/bindings/gen_search.ts b/packages/plugin-runtime-types/src/bindings/gen_search.ts new file mode 100644 index 000000000..f0c56473f --- /dev/null +++ b/packages/plugin-runtime-types/src/bindings/gen_search.ts @@ -0,0 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type PluginSearchResponse = { results: Array, }; + +export type PluginVersion = { id: string, version: string, description: string | null, displayName: string, homepageUrl: string | null, repositoryUrl: string, checksum: string, readme: string | null, yanked: boolean, }; diff --git a/packages/plugin-runtime/src/PluginInstance.ts b/packages/plugin-runtime/src/PluginInstance.ts index 9120d4b96..2cf0921ee 100644 --- a/packages/plugin-runtime/src/PluginInstance.ts +++ b/packages/plugin-runtime/src/PluginInstance.ts @@ -1,5 +1,6 @@ import { BootRequest, + BootResponse, DeleteKeyValueResponse, FindHttpResponsesResponse, FormInput, @@ -52,9 +53,22 @@ export class PluginInstance { // Reload plugin if the JS or package.json changes const windowContextNone: PluginWindowContext = { type: 'none' }; + + this.#mod = {}; + this.#pkg = JSON.parse(readFileSync(this.#pathPkg(), 'utf8')); + + const bootResponse: BootResponse = { + name: this.#pkg.name ?? 'unknown', + version: this.#pkg.version ?? '0.0.1', + }; + const fileChangeCallback = async () => { this.#importModule(); - return this.#sendPayload(windowContextNone, { type: 'reload_response' }, null); + return this.#sendPayload( + windowContextNone, + { type: 'reload_response', ...bootResponse }, + null, + ); }; if (this.#workerData.bootRequest.watch) { @@ -62,12 +76,6 @@ export class PluginInstance { watchFile(this.#pathPkg(), fileChangeCallback); } - this.#mod = {}; - this.#pkg = JSON.parse(readFileSync(this.#pathPkg(), 'utf8')); - - // TODO: Re-implement this now that we're not using workers - // prefixStdout(`[plugin][${this.#pkg.name}] %s`); - this.#importModule(); } diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 6af8a024b..2979c14fb 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -674,6 +674,25 @@ dependencies = [ "serde", ] +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +dependencies = [ + "bzip2-sys", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "cairo-rs" version = "0.18.5" @@ -926,6 +945,32 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.16", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "convert_case" version = "0.4.0" @@ -1080,6 +1125,12 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + [[package]] name = "crypto-common" version = "0.1.6" @@ -1198,6 +1249,12 @@ dependencies = [ "sha2", ] +[[package]] +name = "deflate64" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" + [[package]] name = "deranged" version = "0.4.0" @@ -1326,6 +1383,15 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + [[package]] name = "document-features" version = "0.2.11" @@ -1593,6 +1659,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", + "libz-rs-sys", "miniz_oxide", ] @@ -2920,6 +2987,26 @@ dependencies = [ "winapi", ] +[[package]] +name = "liblzma" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66352d7a8ac12d4877b6e6ea5a9b7650ee094257dc40889955bea5bc5b08c1d0" +dependencies = [ + "liblzma-sys", +] + +[[package]] +name = "liblzma-sys" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b9596486f6d60c3bbe644c0e1be1aa6ccc472ad630fe8927b456973d7cb736" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "libredox" version = "0.1.3" @@ -2956,6 +3043,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libz-rs-sys" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "172a788537a2221661b480fee8dc5f96c580eb34fa88764d3205dc356c7e4221" +dependencies = [ + "zlib-rs", +] + [[package]] name = "libz-sys" version = "1.1.22" @@ -3712,6 +3808,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + [[package]] name = "ordered-stream" version = "0.2.0" @@ -3823,6 +3929,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -4557,9 +4673,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.19" +version = "0.12.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119" +checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813" dependencies = [ "async-compression", "base64 0.22.1", @@ -4577,13 +4693,11 @@ dependencies = [ "hyper-rustls", "hyper-tls", "hyper-util", - "ipnet", "js-sys", "log", "mime", "mime_guess", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", @@ -4596,7 +4710,6 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls", - "tokio-socks", "tokio-util", "tower 0.5.2", "tower-http", @@ -4704,6 +4817,17 @@ dependencies = [ "smallvec", ] +[[package]] +name = "rust-ini" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" +dependencies = [ + "cfg-if", + "ordered-multimap", + "trim-in-place", +] + [[package]] name = "rust_decimal" version = "1.37.1" @@ -5731,6 +5855,26 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "tauri-plugin-deep-link" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4976ac728ebc0487515aa956cfdf200abcc52b784e441493fc544bc6ce369c8" +dependencies = [ + "dunce", + "rust-ini", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-utils", + "thiserror 2.0.12", + "tracing", + "url", + "windows-registry", + "windows-result", +] + [[package]] name = "tauri-plugin-dialog" version = "2.2.2" @@ -5863,6 +6007,7 @@ dependencies = [ "serde", "serde_json", "tauri", + "tauri-plugin-deep-link", "thiserror 2.0.12", "tracing", "windows-sys 0.59.0", @@ -5898,7 +6043,7 @@ dependencies = [ "tokio", "url", "windows-sys 0.59.0", - "zip", + "zip 2.4.2", ] [[package]] @@ -6137,6 +6282,15 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinystr" version = "0.8.1" @@ -6211,18 +6365,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-socks" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" -dependencies = [ - "either", - "futures-util", - "thiserror 1.0.69", - "tokio", -] - [[package]] name = "tokio-stream" version = "0.1.17" @@ -6500,6 +6642,12 @@ dependencies = [ "petgraph", ] +[[package]] +name = "trim-in-place" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" + [[package]] name = "try-lock" version = "0.2.5" @@ -7644,6 +7792,7 @@ dependencies = [ "tauri", "tauri-build", "tauri-plugin-clipboard-manager", + "tauri-plugin-deep-link", "tauri-plugin-dialog", "tauri-plugin-fs", "tauri-plugin-log", @@ -7678,7 +7827,10 @@ name = "yaak-common" version = "0.1.0" dependencies = [ "regex", + "reqwest", + "serde", "tauri", + "thiserror 2.0.12", ] [[package]] @@ -7777,6 +7929,7 @@ dependencies = [ "tauri-plugin", "thiserror 2.0.12", "ts-rs", + "yaak-common", "yaak-models", ] @@ -7823,16 +7976,21 @@ name = "yaak-plugins" version = "0.1.0" dependencies = [ "base64 0.22.1", + "chrono", "dunce", "futures-util", + "hex", "log", "md5", "path-slash", "rand 0.9.1", "regex", + "reqwest", "serde", "serde_json", + "sha2", "tauri", + "tauri-plugin", "tauri-plugin-shell", "thiserror 2.0.12", "tokio", @@ -7842,6 +8000,7 @@ dependencies = [ "yaak-crypto", "yaak-models", "yaak-templates", + "zip-extract", ] [[package]] @@ -8037,6 +8196,20 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] [[package]] name = "zerotrie" @@ -8086,6 +8259,89 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "zip" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "153a6fff49d264c4babdcfa6b4d534747f520e56e8f0f384f3b808c4b64cc1fd" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "deflate64", + "flate2", + "getrandom 0.3.3", + "hmac", + "indexmap 2.9.0", + "liblzma", + "memchr", + "pbkdf2", + "sha1", + "time", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zip-extract" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aed5f10c571472911e37d8f7601a8dfba52b4f7f73a344015291b82ab292faf6" +dependencies = [ + "log", + "thiserror 2.0.12", + "zip 4.0.0", +] + +[[package]] +name = "zlib-rs" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626bd9fa9734751fc50d6060752170984d7053f5a39061f524cda68023d4db8a" + +[[package]] +name = "zopfli" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.15+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "zvariant" version = "5.5.3" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index f15278164..a4b16f1a3 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,9 +1,9 @@ [workspace] members = [ "yaak-crypto", + "yaak-fonts", "yaak-git", "yaak-grpc", - "yaak-fonts", "yaak-http", "yaak-license", "yaak-mac-window", @@ -40,7 +40,7 @@ tauri-build = { version = "2.2.0", features = [] } openssl-sys = { version = "0.9.105", features = ["vendored"] } # For Ubuntu installation to work [dependencies] -chrono = { version = "0.4.31", features = ["serde"] } +chrono = { workspace = true, features = ["serde"] } cookie = "0.18.1" encoding_rs = "0.8.35" eventsource-client = { git = "https://github.com/yaakapp/rust-eventsource-client", version = "0.14.0" } @@ -56,27 +56,28 @@ serde_json = { workspace = true, features = ["raw_value"] } tauri = { workspace = true, features = ["devtools", "protocol-asset"] } tauri-plugin-clipboard-manager = "2.2.2" tauri-plugin-dialog = { workspace = true } -tauri-plugin-fs = "2.2.0" -tauri-plugin-log = { version = "2.3.1", features = ["colored"] } +tauri-plugin-fs = "2.3.0" +tauri-plugin-log = { version = "2.4.0", features = ["colored"] } tauri-plugin-opener = "2.2.6" tauri-plugin-os = "2.2.1" tauri-plugin-shell = { workspace = true } -tauri-plugin-single-instance = "2.2.2" -tauri-plugin-updater = "2.6.1" -tauri-plugin-window-state = "2.2.1" +tauri-plugin-deep-link = "2.3.0" +tauri-plugin-single-instance = { version = "2.2.4", features = ["deep-link"] } +tauri-plugin-updater = "2.7.1" +tauri-plugin-window-state = "2.2.2" thiserror = { workspace = true } tokio = { workspace = true, features = ["sync"] } tokio-stream = "0.1.17" uuid = "1.12.1" yaak-common = { workspace = true } yaak-crypto = { workspace = true } +yaak-fonts = { workspace = true } yaak-git = { path = "yaak-git" } yaak-grpc = { path = "yaak-grpc" } yaak-http = { workspace = true } yaak-license = { path = "yaak-license" } yaak-mac-window = { path = "yaak-mac-window" } yaak-models = { workspace = true } -yaak-fonts = { workspace = true } yaak-plugins = { workspace = true } yaak-sse = { workspace = true } yaak-sync = { workspace = true } @@ -84,7 +85,9 @@ yaak-templates = { workspace = true } yaak-ws = { path = "yaak-ws" } [workspace.dependencies] -reqwest = "0.12.19" +chrono = "0.4.41" +hex = "0.4.3" +reqwest = "0.12.20" serde = "1.0.219" serde_json = "1.0.140" tauri = "2.5.1" @@ -96,7 +99,9 @@ thiserror = "2.0.12" ts-rs = "11.0.1" rustls = { version = "0.23.27", default-features = false } rustls-platform-verifier = "0.6.0" +sha2 = "0.10.9" yaak-common = { path = "yaak-common" } +yaak-crypto = { path = "yaak-crypto" } yaak-fonts = { path = "yaak-fonts" } yaak-http = { path = "yaak-http" } yaak-models = { path = "yaak-models" } @@ -104,4 +109,3 @@ yaak-plugins = { path = "yaak-plugins" } yaak-sse = { path = "yaak-sse" } yaak-sync = { path = "yaak-sync" } yaak-templates = { path = "yaak-templates" } -yaak-crypto = { path = "yaak-crypto" } diff --git a/src-tauri/capabilities/capabilities.json b/src-tauri/capabilities/capabilities.json index 993acf6c9..3eca98615 100644 --- a/src-tauri/capabilities/capabilities.json +++ b/src-tauri/capabilities/capabilities.json @@ -52,11 +52,12 @@ "opener:allow-reveal-item-in-dir", "shell:allow-open", "yaak-crypto:default", - "yaak-git:default", "yaak-fonts:default", + "yaak-git:default", "yaak-license:default", "yaak-mac-window:default", "yaak-models:default", + "yaak-plugins:default", "yaak-sync:default", "yaak-ws:default" ] diff --git a/src-tauri/macos/entitlements.plist b/src-tauri/macos/entitlements.plist index 67fd398e7..7902d8a7e 100644 --- a/src-tauri/macos/entitlements.plist +++ b/src-tauri/macos/entitlements.plist @@ -2,10 +2,6 @@ - - com.apple.security.cs.allow-unsigned-executable-memory - - diff --git a/src-tauri/src/history.rs b/src-tauri/src/history.rs index 1ae629c7b..b1a2882e8 100644 --- a/src-tauri/src/history.rs +++ b/src-tauri/src/history.rs @@ -43,18 +43,6 @@ pub async fn store_launch_history(app_handle: &AppHandle) -> Laun info } -pub fn get_os() -> &'static str { - if cfg!(target_os = "windows") { - "windows" - } else if cfg!(target_os = "macos") { - "macos" - } else if cfg!(target_os = "linux") { - "linux" - } else { - "unknown" - } -} - pub async fn get_num_launches(app_handle: &AppHandle) -> i32 { app_handle.db().get_key_value_int(NAMESPACE, NUM_LAUNCHES_KEY, 0) } diff --git a/src-tauri/src/import.rs b/src-tauri/src/import.rs new file mode 100644 index 000000000..5a118d931 --- /dev/null +++ b/src-tauri/src/import.rs @@ -0,0 +1,105 @@ +use crate::error::Result; +use log::info; +use std::collections::BTreeMap; +use std::fs::read_to_string; +use tauri::{Manager, Runtime, WebviewWindow}; +use yaak_models::models::{ + Environment, Folder, GrpcRequest, HttpRequest, WebsocketRequest, Workspace, +}; +use yaak_models::query_manager::QueryManagerExt; +use yaak_models::util::{BatchUpsertResult, UpdateSource, maybe_gen_id, maybe_gen_id_opt}; +use yaak_plugins::manager::PluginManager; + +pub(crate) async fn import_data( + window: &WebviewWindow, + file_path: &str, +) -> Result { + let plugin_manager = window.state::(); + let file = + read_to_string(file_path).unwrap_or_else(|_| panic!("Unable to read file {}", file_path)); + let file_contents = file.as_str(); + let import_result = plugin_manager.import_data(window, file_contents).await?; + + let mut id_map: BTreeMap = BTreeMap::new(); + + let resources = import_result.resources; + + let workspaces: Vec = resources + .workspaces + .into_iter() + .map(|mut v| { + v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); + v + }) + .collect(); + + let environments: Vec = resources + .environments + .into_iter() + .map(|mut v| { + v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); + v.workspace_id = maybe_gen_id::(v.workspace_id.as_str(), &mut id_map); + v + }) + .collect(); + + let folders: Vec = resources + .folders + .into_iter() + .map(|mut v| { + v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); + v.workspace_id = maybe_gen_id::(v.workspace_id.as_str(), &mut id_map); + v.folder_id = maybe_gen_id_opt::(v.folder_id, &mut id_map); + v + }) + .collect(); + + let http_requests: Vec = resources + .http_requests + .into_iter() + .map(|mut v| { + v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); + v.workspace_id = maybe_gen_id::(v.workspace_id.as_str(), &mut id_map); + v.folder_id = maybe_gen_id_opt::(v.folder_id, &mut id_map); + v + }) + .collect(); + + let grpc_requests: Vec = resources + .grpc_requests + .into_iter() + .map(|mut v| { + v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); + v.workspace_id = maybe_gen_id::(v.workspace_id.as_str(), &mut id_map); + v.folder_id = maybe_gen_id_opt::(v.folder_id, &mut id_map); + v + }) + .collect(); + + let websocket_requests: Vec = resources + .websocket_requests + .into_iter() + .map(|mut v| { + v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); + v.workspace_id = maybe_gen_id::(v.workspace_id.as_str(), &mut id_map); + v.folder_id = maybe_gen_id_opt::(v.folder_id, &mut id_map); + v + }) + .collect(); + + info!("Importing data"); + + let upserted = window.with_tx(|tx| { + tx.batch_upsert( + workspaces, + environments, + folders, + http_requests, + grpc_requests, + websocket_requests, + &UpdateSource::Import, + ) + })?; + + Ok(upserted) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 9f9dffbf2..8adeee2c9 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -3,14 +3,15 @@ use crate::encoding::read_response_body; use crate::error::Error::GenericError; use crate::grpc::{build_metadata, metadata_to_map, resolve_grpc_request}; use crate::http_request::send_http_request; +use crate::import::import_data; use crate::notifications::YaakNotifier; use crate::render::{render_grpc_request, render_template}; use crate::updates::{UpdateMode, UpdateTrigger, YaakUpdater}; -use crate::uri_scheme::handle_uri_scheme; +use crate::uri_scheme::handle_deep_link; use error::Result as YaakResult; use eventsource_client::{EventParser, SSE}; use log::{debug, error, info, warn}; -use std::collections::{BTreeMap, HashMap}; +use std::collections::HashMap; use std::fs::{File, create_dir_all}; use std::path::PathBuf; use std::str::FromStr; @@ -19,24 +20,21 @@ use std::{fs, panic}; use tauri::{AppHandle, Emitter, RunEvent, State, WebviewWindow, is_dev}; use tauri::{Listener, Runtime}; use tauri::{Manager, WindowEvent}; +use tauri_plugin_deep_link::DeepLinkExt; use tauri_plugin_log::fern::colors::ColoredLevelConfig; use tauri_plugin_log::{Builder, Target, TargetKind}; use tauri_plugin_window_state::{AppHandleExt, StateFlags}; -use tokio::fs::read_to_string; use tokio::sync::Mutex; use tokio::task::block_in_place; use yaak_common::window::WorkspaceWindowTrait; use yaak_grpc::manager::{DynamicMessage, GrpcHandle}; use yaak_grpc::{Code, ServiceDefinition, deserialize_message, serialize_message}; use yaak_models::models::{ - CookieJar, Environment, Folder, GrpcConnection, GrpcConnectionState, GrpcEvent, GrpcEventType, - GrpcRequest, HttpRequest, HttpResponse, HttpResponseState, Plugin, WebsocketRequest, Workspace, - WorkspaceMeta, + CookieJar, Environment, GrpcConnection, GrpcConnectionState, GrpcEvent, GrpcEventType, + GrpcRequest, HttpRequest, HttpResponse, HttpResponseState, Plugin, Workspace, WorkspaceMeta, }; use yaak_models::query_manager::QueryManagerExt; -use yaak_models::util::{ - BatchUpsertResult, UpdateSource, get_workspace_export_resources, maybe_gen_id, maybe_gen_id_opt, -}; +use yaak_models::util::{BatchUpsertResult, UpdateSource, get_workspace_export_resources}; use yaak_plugins::events::{ BootResponse, CallHttpRequestActionRequest, FilterResponse, GetHttpAuthenticationConfigResponse, GetHttpAuthenticationSummaryResponse, @@ -55,6 +53,7 @@ mod error; mod grpc; mod history; mod http_request; +mod import; mod notifications; mod plugin_events; mod render; @@ -778,98 +777,9 @@ async fn cmd_get_sse_events(file_path: &str) -> YaakResult> #[tauri::command] async fn cmd_import_data( window: WebviewWindow, - app_handle: AppHandle, - plugin_manager: State<'_, PluginManager>, file_path: &str, ) -> YaakResult { - let file = read_to_string(file_path) - .await - .unwrap_or_else(|_| panic!("Unable to read file {}", file_path)); - let file_contents = file.as_str(); - let import_result = plugin_manager.import_data(&window, file_contents).await?; - - let mut id_map: BTreeMap = BTreeMap::new(); - - let resources = import_result.resources; - - let workspaces: Vec = resources - .workspaces - .into_iter() - .map(|mut v| { - v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); - v - }) - .collect(); - - let environments: Vec = resources - .environments - .into_iter() - .map(|mut v| { - v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); - v.workspace_id = maybe_gen_id::(v.workspace_id.as_str(), &mut id_map); - v - }) - .collect(); - - let folders: Vec = resources - .folders - .into_iter() - .map(|mut v| { - v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); - v.workspace_id = maybe_gen_id::(v.workspace_id.as_str(), &mut id_map); - v.folder_id = maybe_gen_id_opt::(v.folder_id, &mut id_map); - v - }) - .collect(); - - let http_requests: Vec = resources - .http_requests - .into_iter() - .map(|mut v| { - v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); - v.workspace_id = maybe_gen_id::(v.workspace_id.as_str(), &mut id_map); - v.folder_id = maybe_gen_id_opt::(v.folder_id, &mut id_map); - v - }) - .collect(); - - let grpc_requests: Vec = resources - .grpc_requests - .into_iter() - .map(|mut v| { - v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); - v.workspace_id = maybe_gen_id::(v.workspace_id.as_str(), &mut id_map); - v.folder_id = maybe_gen_id_opt::(v.folder_id, &mut id_map); - v - }) - .collect(); - - let websocket_requests: Vec = resources - .websocket_requests - .into_iter() - .map(|mut v| { - v.id = maybe_gen_id::(v.id.as_str(), &mut id_map); - v.workspace_id = maybe_gen_id::(v.workspace_id.as_str(), &mut id_map); - v.folder_id = maybe_gen_id_opt::(v.folder_id, &mut id_map); - v - }) - .collect(); - - info!("Importing data"); - - let upserted = app_handle.with_tx(|tx| { - tx.batch_upsert( - workspaces, - environments, - folders, - http_requests, - grpc_requests, - websocket_requests, - &UpdateSource::Import, - ) - })?; - - Ok(upserted) + import_data(&window, file_path).await } #[tauri::command] @@ -1066,7 +976,7 @@ async fn cmd_install_plugin( app_handle: AppHandle, window: WebviewWindow, ) -> YaakResult { - plugin_manager.add_plugin_by_dir(&PluginWindowContext::new(&window), &directory, true).await?; + plugin_manager.add_plugin_by_dir(&PluginWindowContext::new(&window), &directory).await?; Ok(app_handle.db().upsert_plugin( &Plugin { @@ -1255,6 +1165,7 @@ pub fn run() { .plugin(tauri_plugin_clipboard_manager::init()) .plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_window_state::Builder::default().build()) + .plugin(tauri_plugin_deep_link::init()) .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_updater::Builder::default().build()) .plugin(tauri_plugin_dialog::init()) @@ -1272,6 +1183,21 @@ pub fn run() { builder .setup(|app| { + { + let app_handle = app.app_handle().clone(); + app.deep_link().on_open_url(move |event| { + info!("Handling deep link open"); + let app_handle = app_handle.clone(); + tauri::async_runtime::spawn(async move { + for url in event.urls() { + if let Err(e) = handle_deep_link(&app_handle, &url).await { + warn!("Failed to handle deep link {}: {e:?}", url.to_string()); + }; + } + }); + }); + }; + let app_data_dir = app.path().app_data_dir().unwrap(); create_dir_all(app_data_dir.clone()).expect("Problem creating App directory!"); @@ -1332,7 +1258,6 @@ pub fn run() { crate::commands::cmd_secure_template, crate::commands::cmd_show_workspace_key, ]) - .register_uri_scheme_protocol("yaak", handle_uri_scheme) .build(tauri::generate_context!()) .expect("error while running tauri application") .run(|app_handle, event| { diff --git a/src-tauri/src/notifications.rs b/src-tauri/src/notifications.rs index 29fa1bc65..88b28577e 100644 --- a/src-tauri/src/notifications.rs +++ b/src-tauri/src/notifications.rs @@ -1,13 +1,14 @@ use std::time::SystemTime; use crate::error::Result; -use crate::history::{get_num_launches, get_os}; +use crate::history::get_num_launches; use chrono::{DateTime, Duration, Utc}; use log::debug; use reqwest::Method; use serde::{Deserialize, Serialize}; use serde_json::Value; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow}; +use yaak_common::platform::get_os; use yaak_license::{LicenseCheckStatus, check_license}; use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::UpdateSource; diff --git a/src-tauri/src/plugin_events.rs b/src-tauri/src/plugin_events.rs index 9da132499..9ebac1db9 100644 --- a/src-tauri/src/plugin_events.rs +++ b/src-tauri/src/plugin_events.rs @@ -126,7 +126,7 @@ pub(crate) async fn handle_plugin_event( Box::pin(handle_plugin_event(app_handle, &toast_event, plugin_handle)).await; None } - InternalEventPayload::ReloadResponse(_) => { + InternalEventPayload::ReloadResponse(r) => { let plugins = app_handle.db().list_plugins().unwrap(); for plugin in plugins { if plugin.directory != plugin_handle.dir { @@ -142,7 +142,7 @@ pub(crate) async fn handle_plugin_event( let toast_event = plugin_handle.build_event_to_send( &window_context, &InternalEventPayload::ShowToastRequest(ShowToastRequest { - message: format!("Reloaded plugin {}", plugin_handle.dir), + message: format!("Reloaded plugin {}@{}", r.name, r.version), icon: Some(Icon::Info), ..Default::default() }), diff --git a/src-tauri/src/uri_scheme.rs b/src-tauri/src/uri_scheme.rs index a9a932dd7..eff526967 100644 --- a/src-tauri/src/uri_scheme.rs +++ b/src-tauri/src/uri_scheme.rs @@ -1,25 +1,74 @@ +use crate::error::Result; +use crate::import::import_data; use log::{info, warn}; -use tauri::{Manager, Runtime, UriSchemeContext}; +use std::collections::HashMap; +use tauri::{AppHandle, Emitter, Manager, Runtime, Url}; +use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogKind}; +use yaak_plugins::api::get_plugin; +use yaak_plugins::events::{Color, ShowToastRequest}; +use yaak_plugins::install::download_and_install; -pub(crate) fn handle_uri_scheme( - a: UriSchemeContext, - req: http::Request>, -) -> http::Response> { - println!("------------- Yaak URI scheme invoked!"); - let uri = req.uri(); - let window = a - .app_handle() - .get_webview_window(a.webview_label()) - .expect("Failed to get webview window for URI scheme event"); - info!("Yaak URI scheme invoked with {uri:?} {window:?}"); +pub(crate) async fn handle_deep_link( + app_handle: &AppHandle, + url: &Url, +) -> Result<()> { + let command = url.domain().unwrap_or_default(); + info!("Yaak URI scheme invoked {}?{}", command, url.query().unwrap_or_default()); - let path = uri.path(); - if path == "/data/import" { - warn!("TODO: import data") - } else if path == "/plugins/install" { - warn!("TODO: install plugin") + let query_map: HashMap = url.query_pairs().into_owned().collect(); + let windows = app_handle.webview_windows(); + let (_, window) = windows.iter().next().unwrap(); + + match command { + "install-plugin" => { + let name = query_map.get("name").unwrap(); + let version = query_map.get("version").cloned(); + let plugin_version = get_plugin(&app_handle, &name, version).await?; + _ = window.set_focus(); + let confirmed_install = app_handle + .dialog() + .message(format!( + "Install plugin {}@{}?", + plugin_version.name, plugin_version.version + )) + .kind(MessageDialogKind::Info) + .buttons(MessageDialogButtons::OkCustom("Install".to_string())) + .blocking_show(); + if !confirmed_install { + // Cancelled installation + return Ok(()); + } + + download_and_install(window, &plugin_version).await?; + app_handle.emit( + "show_toast", + ShowToastRequest { + message: format!( + "Installed {}@{}", + plugin_version.name, plugin_version.version + ), + color: Some(Color::Success), + icon: None, + }, + )?; + } + "import-data" => { + let file_path = query_map.get("path").unwrap(); + let results = import_data(window, file_path).await?; + _ = window.set_focus(); + window.emit( + "show_toast", + ShowToastRequest { + message: format!("Imported data for {} workspaces", results.workspaces.len()), + color: Some(Color::Success), + icon: None, + }, + )?; + } + _ => { + warn!("Unknown deep link command: {command}"); + } } - let msg = format!("No handler found for {path}"); - tauri::http::Response::builder().status(404).body(msg.as_bytes().to_vec()).unwrap() + Ok(()) } diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 16a28fac4..c7a98979a 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -23,7 +23,6 @@ }, "plugins": { "deep-link": { - "mobile": [], "desktop": { "schemes": [ "yaak" diff --git a/src-tauri/yaak-common/Cargo.toml b/src-tauri/yaak-common/Cargo.toml index 1186bf988..be0337517 100644 --- a/src-tauri/yaak-common/Cargo.toml +++ b/src-tauri/yaak-common/Cargo.toml @@ -6,4 +6,7 @@ publish = false [dependencies] tauri = { workspace = true } +reqwest = { workspace = true, features = ["system-proxy", "gzip"] } +thiserror = { workspace = true } regex = "1.11.0" +serde = { workspace = true, features = ["derive"] } diff --git a/src-tauri/yaak-common/src/api_client.rs b/src-tauri/yaak-common/src/api_client.rs new file mode 100644 index 000000000..79c40595c --- /dev/null +++ b/src-tauri/yaak-common/src/api_client.rs @@ -0,0 +1,23 @@ +use crate::error::Result; +use crate::platform::get_ua_platform; +use reqwest::Client; +use std::time::Duration; +use tauri::http::{HeaderMap, HeaderValue}; +use tauri::{AppHandle, Runtime}; + +pub fn yaak_api_client(app_handle: &AppHandle) -> Result { + let platform = get_ua_platform(); + let version = app_handle.package_info().version.clone(); + let ua = format!("Yaak/{version} ({platform})"); + let mut default_headers = HeaderMap::new(); + default_headers.insert("Accept", HeaderValue::from_str("application/json").unwrap()); + + let client = reqwest::ClientBuilder::new() + .timeout(Duration::from_secs(20)) + .default_headers(default_headers) + .gzip(true) + .user_agent(ua) + .build()?; + + Ok(client) +} diff --git a/src-tauri/yaak-common/src/error.rs b/src-tauri/yaak-common/src/error.rs new file mode 100644 index 000000000..46a9c103b --- /dev/null +++ b/src-tauri/yaak-common/src/error.rs @@ -0,0 +1,19 @@ +use serde::{Serialize, Serializer}; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error(transparent)] + ReqwestError(#[from] reqwest::Error), +} + +impl Serialize for Error { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: Serializer, + { + serializer.serialize_str(self.to_string().as_ref()) + } +} + +pub type Result = std::result::Result; diff --git a/src-tauri/yaak-common/src/lib.rs b/src-tauri/yaak-common/src/lib.rs index d42d7dbec..6229a01f4 100644 --- a/src-tauri/yaak-common/src/lib.rs +++ b/src-tauri/yaak-common/src/lib.rs @@ -1 +1,4 @@ -pub mod window; \ No newline at end of file +pub mod window; +pub mod platform; +pub mod api_client; +pub mod error; \ No newline at end of file diff --git a/src-tauri/yaak-common/src/platform.rs b/src-tauri/yaak-common/src/platform.rs new file mode 100644 index 000000000..4e1f2587c --- /dev/null +++ b/src-tauri/yaak-common/src/platform.rs @@ -0,0 +1,23 @@ +pub fn get_os() -> &'static str { + if cfg!(target_os = "windows") { + "windows" + } else if cfg!(target_os = "macos") { + "macos" + } else if cfg!(target_os = "linux") { + "linux" + } else { + "unknown" + } +} + +pub fn get_ua_platform() -> &'static str { + if cfg!(target_os = "windows") { + "Win" + } else if cfg!(target_os = "macos") { + "Mac" + } else if cfg!(target_os = "linux") { + "Linux" + } else { + "Unknown" + } +} diff --git a/src-tauri/yaak-crypto/Cargo.toml b/src-tauri/yaak-crypto/Cargo.toml index 0203c011f..9f8380383 100644 --- a/src-tauri/yaak-crypto/Cargo.toml +++ b/src-tauri/yaak-crypto/Cargo.toml @@ -13,7 +13,7 @@ keyring = { version = "4.0.0-rc.1" } log = "0.4.26" serde = { workspace = true, features = ["derive"] } tauri = { workspace = true } -thiserror = "2.0.12" +thiserror = { workspace = true } yaak-models = { workspace = true } [build-dependencies] diff --git a/src-tauri/yaak-git/Cargo.toml b/src-tauri/yaak-git/Cargo.toml index 0fe6f69ec..7698382ee 100644 --- a/src-tauri/yaak-git/Cargo.toml +++ b/src-tauri/yaak-git/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" publish = false [dependencies] -chrono = { version = "0.4.38", features = ["serde"] } +chrono = { workspace = true, features = ["serde"] } git2 = { version = "0.20.0", features = ["vendored-libgit2", "vendored-openssl"] } log = "0.4.22" serde = { workspace = true, features = ["derive"] } diff --git a/src-tauri/yaak-license/Cargo.toml b/src-tauri/yaak-license/Cargo.toml index 67d62cb03..38dc136a6 100644 --- a/src-tauri/yaak-license/Cargo.toml +++ b/src-tauri/yaak-license/Cargo.toml @@ -15,6 +15,7 @@ tauri = { workspace = true } thiserror = { workspace = true } ts-rs = { workspace = true } yaak-models = { workspace = true } +yaak-common = { workspace = true } [build-dependencies] tauri-plugin = { workspace = true, features = ["build"] } diff --git a/src-tauri/yaak-license/src/lib.rs b/src-tauri/yaak-license/src/lib.rs index dd8fd540c..03b76bfcd 100644 --- a/src-tauri/yaak-license/src/lib.rs +++ b/src-tauri/yaak-license/src/lib.rs @@ -16,15 +16,3 @@ pub fn init() -> TauriPlugin { .invoke_handler(generate_handler![check, activate, deactivate]) .build() } - -pub(crate) fn get_os() -> &'static str { - if cfg!(target_os = "windows") { - "windows" - } else if cfg!(target_os = "macos") { - "macos" - } else if cfg!(target_os = "linux") { - "linux" - } else { - "unknown" - } -} diff --git a/src-tauri/yaak-license/src/license.rs b/src-tauri/yaak-license/src/license.rs index 9e22f8581..48c40635b 100644 --- a/src-tauri/yaak-license/src/license.rs +++ b/src-tauri/yaak-license/src/license.rs @@ -7,6 +7,7 @@ use std::ops::Add; use std::time::Duration; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow, is_dev}; use ts_rs::TS; +use yaak_common::platform::get_os; use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::UpdateSource; @@ -68,7 +69,7 @@ pub async fn activate_license( let client = reqwest::Client::new(); let payload = ActivateLicenseRequestPayload { license_key: license_key.to_string(), - app_platform: crate::get_os().to_string(), + app_platform: get_os().to_string(), app_version: window.app_handle().package_info().version.to_string(), }; let response = client.post(build_url("/licenses/activate")).json(&payload).send().await?; @@ -107,7 +108,7 @@ pub async fn deactivate_license(window: &WebviewWindow) -> Result let client = reqwest::Client::new(); let path = format!("/licenses/activations/{}/deactivate", activation_id); let payload = DeactivateLicenseRequestPayload { - app_platform: crate::get_os().to_string(), + app_platform: get_os().to_string(), app_version: window.app_handle().package_info().version.to_string(), }; let response = client.post(build_url(&path)).json(&payload).send().await?; @@ -149,7 +150,7 @@ pub enum LicenseCheckStatus { pub async fn check_license(window: &WebviewWindow) -> Result { let payload = CheckActivationRequestPayload { - app_platform: crate::get_os().to_string(), + app_platform: get_os().to_string(), app_version: window.package_info().version.to_string(), }; let activation_id = get_activation_id(window.app_handle()).await; diff --git a/src-tauri/yaak-models/Cargo.toml b/src-tauri/yaak-models/Cargo.toml index b69bb5e5e..ba26760dc 100644 --- a/src-tauri/yaak-models/Cargo.toml +++ b/src-tauri/yaak-models/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] chrono = { version = "0.4.38", features = ["serde"] } -hex = "0.4.3" +hex = { workspace = true } include_dir = "0.7" log = "0.4.22" nanoid = "0.4.0" @@ -18,10 +18,10 @@ sea-query = { version = "0.32.1", features = ["with-chrono", "attr"] } sea-query-rusqlite = { version = "0.7.0", features = ["with-chrono"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } -sha2 = "0.10.9" -tauri = { workspace = true} +sha2 = { workspace = true } +tauri = { workspace = true } tauri-plugin-dialog = { workspace = true } -thiserror = "2.0.11" +thiserror = { workspace = true } tokio = { workspace = true } ts-rs = { workspace = true, features = ["chrono-impl", "serde-json-impl"] } diff --git a/src-tauri/yaak-models/bindings/gen_models.ts b/src-tauri/yaak-models/bindings/gen_models.ts index 7da8e425a..c36185b27 100644 --- a/src-tauri/yaak-models/bindings/gen_models.ts +++ b/src-tauri/yaak-models/bindings/gen_models.ts @@ -58,7 +58,7 @@ export type Plugin = { model: "plugin", id: string, createdAt: string, updatedAt export type PluginKeyValue = { model: "plugin_key_value", createdAt: string, updatedAt: string, pluginName: string, key: string, value: string, }; -export type ProxySetting = { "type": "enabled", disabled: boolean, http: string, https: string, auth: ProxySettingAuth | null, bypass: string, } | { "type": "disabled" }; +export type ProxySetting = { "type": "enabled", http: string, https: string, auth: ProxySettingAuth | null, bypass: string, disabled: boolean, } | { "type": "disabled" }; export type ProxySettingAuth = { user: string, password: string, }; diff --git a/src-tauri/yaak-plugins/Cargo.toml b/src-tauri/yaak-plugins/Cargo.toml index f34d7630c..3d877ca63 100644 --- a/src-tauri/yaak-plugins/Cargo.toml +++ b/src-tauri/yaak-plugins/Cargo.toml @@ -1,10 +1,12 @@ [package] name = "yaak-plugins" +links = "yaak-plugins" version = "0.1.0" edition = "2024" publish = false [dependencies] +base64 = "0.22.1" dunce = "1.0.4" futures-util = "0.3.30" log = "0.4.21" @@ -12,16 +14,23 @@ md5 = "0.7.0" path-slash = "0.2.1" rand = "0.9.0" regex = "1.10.6" +reqwest = { workspace = true, features = ["json"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } tauri = { workspace = true } tauri-plugin-shell = { workspace = true } -thiserror = "2.0.7" +thiserror = { workspace = true } tokio = { workspace = true, features = ["macros", "rt-multi-thread", "process"] } tokio-tungstenite = "0.26.1" ts-rs = { workspace = true, features = ["import-esm"] } +sha2 = { workspace = true } +yaak-common = { workspace = true } +yaak-crypto = { workspace = true } yaak-models = { workspace = true } yaak-templates = { workspace = true } -yaak-crypto = { workspace = true } -yaak-common = { workspace = true } -base64 = "0.22.1" +zip-extract = "0.4.0" +chrono = { workspace = true } +hex = { workspace = true } + +[build-dependencies] +tauri-plugin = { workspace = true, features = ["build"] } diff --git a/src-tauri/yaak-plugins/bindings/gen_events.ts b/src-tauri/yaak-plugins/bindings/gen_events.ts index 1a82fb1be..001a58d03 100644 --- a/src-tauri/yaak-plugins/bindings/gen_events.ts +++ b/src-tauri/yaak-plugins/bindings/gen_events.ts @@ -372,7 +372,7 @@ export type ImportResponse = { resources: ImportResources, }; export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: PluginWindowContext, payload: InternalEventPayload, }; -export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "list_cookie_names_request" } & ListCookieNamesRequest | { "type": "list_cookie_names_response" } & ListCookieNamesResponse | { "type": "get_cookie_value_request" } & GetCookieValueRequest | { "type": "get_cookie_value_response" } & GetCookieValueResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; +export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & BootResponse | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "list_cookie_names_request" } & ListCookieNamesRequest | { "type": "list_cookie_names_response" } & ListCookieNamesResponse | { "type": "get_cookie_value_request" } & GetCookieValueRequest | { "type": "get_cookie_value_response" } & GetCookieValueResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; export type JsonPrimitive = string | number | boolean | null; diff --git a/src-tauri/yaak-plugins/bindings/gen_search.ts b/src-tauri/yaak-plugins/bindings/gen_search.ts new file mode 100644 index 000000000..f0c56473f --- /dev/null +++ b/src-tauri/yaak-plugins/bindings/gen_search.ts @@ -0,0 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type PluginSearchResponse = { results: Array, }; + +export type PluginVersion = { id: string, version: string, description: string | null, displayName: string, homepageUrl: string | null, repositoryUrl: string, checksum: string, readme: string | null, yanked: boolean, }; diff --git a/src-tauri/yaak-plugins/build.rs b/src-tauri/yaak-plugins/build.rs new file mode 100644 index 000000000..88527efaf --- /dev/null +++ b/src-tauri/yaak-plugins/build.rs @@ -0,0 +1,5 @@ +const COMMANDS: &[&str] = &["search", "install"]; + +fn main() { + tauri_plugin::Builder::new(COMMANDS).build(); +} diff --git a/src-tauri/yaak-plugins/index.ts b/src-tauri/yaak-plugins/index.ts index 2a389fc3b..10ec0c898 100644 --- a/src-tauri/yaak-plugins/index.ts +++ b/src-tauri/yaak-plugins/index.ts @@ -1,2 +1,14 @@ +import { invoke } from '@tauri-apps/api/core'; +import { PluginSearchResponse, PluginVersion } from './bindings/gen_search'; + export * from './bindings/gen_models'; export * from './bindings/gen_events'; +export * from './bindings/gen_search'; + +export async function searchPlugins(query: string) { + return invoke('plugin:yaak-plugins|search', { query }); +} + +export async function installPlugin(plugin: PluginVersion) { + return invoke('plugin:yaak-plugins|install', { plugin }); +} diff --git a/src-tauri/yaak-plugins/permissions/default.toml b/src-tauri/yaak-plugins/permissions/default.toml new file mode 100644 index 000000000..054af4e37 --- /dev/null +++ b/src-tauri/yaak-plugins/permissions/default.toml @@ -0,0 +1,3 @@ +[default] +description = "Default permissions for the plugin" +permissions = ["allow-search", "allow-install"] diff --git a/src-tauri/yaak-plugins/src/api.rs b/src-tauri/yaak-plugins/src/api.rs new file mode 100644 index 000000000..26e63463f --- /dev/null +++ b/src-tauri/yaak-plugins/src/api.rs @@ -0,0 +1,67 @@ +use crate::commands::{PluginSearchResponse, PluginVersion}; +use crate::error::Result; +use reqwest::{Response, Url}; +use std::str::FromStr; +use log::info; +use tauri::{AppHandle, Runtime, is_dev}; +use yaak_common::api_client::yaak_api_client; +use crate::error::Error::ApiErr; + +pub async fn get_plugin( + app_handle: &AppHandle, + name: &str, + version: Option, +) -> Result { + info!("Getting plugin: {name} {version:?}"); + let mut url = base_url(&format!("/{name}")); + if let Some(version) = version { + let mut query_pairs = url.query_pairs_mut(); + query_pairs.append_pair("version", &version); + }; + let resp = yaak_api_client(app_handle)?.get(url.clone()).send().await?; + if !resp.status().is_success() { + return Err(ApiErr(format!("{} response to {}", resp.status(), url.to_string()))); + } + Ok(resp.json().await?) +} + +pub async fn download_plugin_archive( + app_handle: &AppHandle, + plugin_version: &PluginVersion, +) -> Result { + let name = plugin_version.name.clone(); + let version = plugin_version.version.clone(); + info!("Downloading plugin: {name} {version}"); + let mut url = base_url(&format!("/{}/download", name)); + { + let mut query_pairs = url.query_pairs_mut(); + query_pairs.append_pair("version", &version); + }; + let resp = yaak_api_client(app_handle)?.get(url.clone()).send().await?; + if !resp.status().is_success() { + return Err(ApiErr(format!("{} response to {}", resp.status(), url.to_string()))); + } + Ok(resp) +} + +pub async fn search_plugins( + app_handle: &AppHandle, + query: &str, +) -> Result { + let mut url = base_url("/search"); + { + let mut query_pairs = url.query_pairs_mut(); + query_pairs.append_pair("query", query); + }; + let resp = yaak_api_client(app_handle)?.get(url).send().await?; + Ok(resp.json().await?) +} + +fn base_url(path: &str) -> Url { + let base_url = if is_dev() { + "http://localhost:9444/api/v1/plugins" + } else { + "https://api.yaak.app/api/v1/plugins" + }; + Url::from_str(&format!("{base_url}{path}")).unwrap() +} diff --git a/src-tauri/yaak-plugins/src/checksum.rs b/src-tauri/yaak-plugins/src/checksum.rs new file mode 100644 index 000000000..6b525c771 --- /dev/null +++ b/src-tauri/yaak-plugins/src/checksum.rs @@ -0,0 +1,8 @@ +use sha2::{Digest, Sha256}; + +pub(crate) fn compute_checksum(bytes: impl AsRef<[u8]>) -> String { + let mut hasher = Sha256::new(); + hasher.update(&bytes); + let hash = hasher.finalize(); + hex::encode(hash) +} diff --git a/src-tauri/yaak-plugins/src/commands.rs b/src-tauri/yaak-plugins/src/commands.rs new file mode 100644 index 000000000..460f3671e --- /dev/null +++ b/src-tauri/yaak-plugins/src/commands.rs @@ -0,0 +1,45 @@ +use crate::api::search_plugins; +use crate::error::Result; +use crate::install::download_and_install; +use serde::{Deserialize, Serialize}; +use tauri::{AppHandle, Runtime, WebviewWindow, command}; +use ts_rs::TS; + +#[command] +pub(crate) async fn search( + app_handle: AppHandle, + query: &str, +) -> Result { + search_plugins(&app_handle, query).await +} + +#[command] +pub(crate) async fn install( + window: WebviewWindow, + plugin: PluginVersion, +) -> Result { + download_and_install(&window, &plugin).await +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS, PartialEq)] +#[serde(rename_all = "camelCase")] +#[ts(export, export_to = "gen_search.ts")] +pub struct PluginSearchResponse { + pub results: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS, PartialEq)] +#[serde(rename_all = "camelCase")] +#[ts(export, export_to = "gen_search.ts")] +pub struct PluginVersion { + pub id: String, + pub version: String, + pub description: Option, + pub name: String, + pub display_name: String, + pub homepage_url: Option, + pub repository_url: Option, + pub checksum: String, + pub readme: Option, + pub yanked: bool, +} diff --git a/src-tauri/yaak-plugins/src/error.rs b/src-tauri/yaak-plugins/src/error.rs index 2996425a9..64c515ec2 100644 --- a/src-tauri/yaak-plugins/src/error.rs +++ b/src-tauri/yaak-plugins/src/error.rs @@ -1,4 +1,5 @@ use crate::events::InternalEvent; +use serde::{Serialize, Serializer}; use thiserror::Error; use tokio::io; use tokio::sync::mpsc::error::SendError; @@ -8,9 +9,12 @@ pub enum Error { #[error(transparent)] CryptoErr(#[from] yaak_crypto::error::Error), + #[error(transparent)] + DbErr(#[from] yaak_models::error::Error), + #[error(transparent)] TemplateErr(#[from] yaak_templates::error::Error), - + #[error("IO error: {0}")] IoErr(#[from] io::Error), @@ -23,8 +27,17 @@ pub enum Error { #[error("Grpc send error: {0}")] GrpcSendErr(#[from] SendError), + #[error("Failed to send request: {0}")] + RequestError(#[from] reqwest::Error), + #[error("JSON error: {0}")] JsonErr(#[from] serde_json::Error), + + #[error("API Error: {0}")] + ApiErr(String), + + #[error(transparent)] + CommonError(#[from] yaak_common::error::Error), #[error("Timeout elapsed: {0}")] TimeoutElapsed(#[from] tokio::time::error::Elapsed), @@ -38,6 +51,9 @@ pub enum Error { #[error("Plugin error: {0}")] PluginErr(String), + #[error("zip error: {0}")] + ZipError(#[from] zip_extract::ZipExtractError), + #[error("Client not initialized error")] ClientNotInitializedErr, @@ -45,4 +61,13 @@ pub enum Error { UnknownEventErr, } +impl Serialize for Error { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: Serializer, + { + serializer.serialize_str(self.to_string().as_ref()) + } +} + pub type Result = std::result::Result; diff --git a/src-tauri/yaak-plugins/src/events.rs b/src-tauri/yaak-plugins/src/events.rs index c9786cfb3..edd28046a 100644 --- a/src-tauri/yaak-plugins/src/events.rs +++ b/src-tauri/yaak-plugins/src/events.rs @@ -67,7 +67,7 @@ pub enum InternalEventPayload { BootResponse(BootResponse), ReloadRequest(EmptyPayload), - ReloadResponse(EmptyPayload), + ReloadResponse(BootResponse), TerminateRequest, TerminateResponse, diff --git a/src-tauri/yaak-plugins/src/install.rs b/src-tauri/yaak-plugins/src/install.rs new file mode 100644 index 000000000..e1146263e --- /dev/null +++ b/src-tauri/yaak-plugins/src/install.rs @@ -0,0 +1,60 @@ +use crate::api::download_plugin_archive; +use crate::checksum::compute_checksum; +use crate::commands::PluginVersion; +use crate::error::Error::PluginErr; +use crate::error::Result; +use crate::events::PluginWindowContext; +use crate::manager::PluginManager; +use chrono::Utc; +use log::info; +use std::fs::create_dir_all; +use std::io::Cursor; +use tauri::{Manager, Runtime, WebviewWindow}; +use yaak_models::models::Plugin; +use yaak_models::query_manager::QueryManagerExt; +use yaak_models::util::{UpdateSource, generate_id}; + +pub async fn download_and_install( + window: &WebviewWindow, + plugin_version: &PluginVersion, +) -> Result { + let resp = download_plugin_archive(window.app_handle(), &plugin_version).await?; + let bytes = resp.bytes().await?; + + let checksum = compute_checksum(&bytes); + if checksum != plugin_version.checksum { + return Err(PluginErr(format!( + "Checksum mismatch {}b {checksum} != {}", + bytes.len(), + plugin_version.checksum + ))); + } + + info!("Checksum matched {}", checksum); + + let plugin_dir = window.path().app_data_dir()?.join("plugins").join(generate_id()); + let plugin_dir_str = plugin_dir.to_str().unwrap().to_string(); + create_dir_all(&plugin_dir)?; + + zip_extract::extract(Cursor::new(&bytes), &plugin_dir, true)?; + info!("Extracted plugin {} to {}", plugin_version.id, plugin_dir_str); + + let plugin_manager = window.state::(); + plugin_manager.add_plugin_by_dir(&PluginWindowContext::new(&window), &plugin_dir_str).await?; + + let p = window.db().upsert_plugin( + &Plugin { + id: plugin_version.id.clone(), + checked_at: Some(Utc::now().naive_utc()), + directory: plugin_dir_str.clone(), + enabled: true, + url: None, + ..Default::default() + }, + &UpdateSource::Background, + )?; + + info!("Installed plugin {} to {}", plugin_version.id, plugin_dir_str); + + Ok(p.id) +} diff --git a/src-tauri/yaak-plugins/src/lib.rs b/src-tauri/yaak-plugins/src/lib.rs index 6976732b7..960b3dd56 100644 --- a/src-tauri/yaak-plugins/src/lib.rs +++ b/src-tauri/yaak-plugins/src/lib.rs @@ -1,9 +1,11 @@ +use crate::commands::{install, search}; use crate::manager::PluginManager; use log::info; use std::process::exit; use tauri::plugin::{Builder, TauriPlugin}; -use tauri::{Manager, RunEvent, Runtime, State}; +use tauri::{Manager, RunEvent, Runtime, State, generate_handler}; +mod commands; pub mod error; pub mod events; pub mod manager; @@ -13,9 +15,13 @@ pub mod plugin_handle; mod server_ws; pub mod template_callback; mod util; +mod checksum; +pub mod api; +pub mod install; pub fn init() -> TauriPlugin { Builder::new("yaak-plugins") + .invoke_handler(generate_handler![search, install]) .setup(|app_handle, _| { let manager = PluginManager::new(app_handle.clone()); app_handle.manage(manager.clone()); diff --git a/src-tauri/yaak-plugins/src/manager.rs b/src-tauri/yaak-plugins/src/manager.rs index 0f431a093..4bec172af 100644 --- a/src-tauri/yaak-plugins/src/manager.rs +++ b/src-tauri/yaak-plugins/src/manager.rs @@ -18,7 +18,7 @@ use crate::server_ws::PluginRuntimeServerWebsocket; use log::{error, info, warn}; use std::collections::HashMap; use std::env; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::sync::Arc; use std::time::Duration; use tauri::path::BaseDirectory; @@ -38,12 +38,13 @@ pub struct PluginManager { plugins: Arc>>, kill_tx: tokio::sync::watch::Sender, ws_service: Arc, + vendored_plugin_dir: PathBuf, + installed_plugin_dir: PathBuf, } #[derive(Clone)] struct PluginCandidate { dir: String, - watch: bool, } impl PluginManager { @@ -56,11 +57,21 @@ impl PluginManager { let ws_service = PluginRuntimeServerWebsocket::new(events_tx, client_disconnect_tx, client_connect_tx); + let vendored_plugin_dir = app_handle + .path() + .resolve("vendored/plugins", BaseDirectory::Resource) + .expect("failed to resolve plugin directory resource"); + + let installed_plugin_dir = + app_handle.path().app_data_dir().expect("failed to get app data dir"); + let plugin_manager = PluginManager { plugins: Default::default(), subscribers: Default::default(), ws_service: Arc::new(ws_service.clone()), kill_tx: kill_server_tx, + vendored_plugin_dir, + installed_plugin_dir, }; // Forward events to subscribers @@ -135,18 +146,13 @@ impl PluginManager { &self, app_handle: &AppHandle, ) -> Vec { - let bundled_plugins_dir = &app_handle - .path() - .resolve("vendored/plugins", BaseDirectory::Resource) - .expect("failed to resolve plugin directory resource"); - let plugins_dir = if is_dev() { // Use plugins directly for easy development env::current_dir() .map(|cwd| cwd.join("../plugins").canonicalize().unwrap()) - .unwrap_or_else(|_| bundled_plugins_dir.clone()) + .unwrap_or_else(|_| self.vendored_plugin_dir.to_path_buf()) } else { - bundled_plugins_dir.clone() + self.vendored_plugin_dir.to_path_buf() }; info!("Loading bundled plugins from {plugins_dir:?}"); @@ -155,13 +161,7 @@ impl PluginManager { .await .expect(format!("Failed to read plugins dir: {:?}", plugins_dir).as_str()) .iter() - .map(|d| { - let is_vendored = plugins_dir.starts_with(bundled_plugins_dir); - PluginCandidate { - dir: d.into(), - watch: !is_vendored, - } - }) + .map(|d| PluginCandidate { dir: d.into() }) .collect(); let plugins = app_handle.db().list_plugins().unwrap_or_default(); @@ -169,7 +169,6 @@ impl PluginManager { .iter() .map(|p| PluginCandidate { dir: p.directory.to_owned(), - watch: true, }) .collect(); @@ -203,7 +202,6 @@ impl PluginManager { &self, window_context: &PluginWindowContext, dir: &str, - watch: bool, ) -> Result<()> { info!("Adding plugin by dir {dir}"); let maybe_tx = self.ws_service.app_to_plugin_events_tx.lock().await; @@ -212,6 +210,9 @@ impl PluginManager { Some(tx) => tx, }; let plugin_handle = PluginHandle::new(dir, tx.clone()); + let dir_path = Path::new(dir); + let is_vendored = dir_path.starts_with(self.vendored_plugin_dir.as_path()); + let is_installed = dir_path.starts_with(self.installed_plugin_dir.as_path()); // Boot the plugin let event = timeout( @@ -221,7 +222,7 @@ impl PluginManager { &plugin_handle, &InternalEventPayload::BootRequest(BootRequest { dir: dir.to_string(), - watch, + watch: !is_vendored && !is_installed, }), ), ) @@ -256,10 +257,7 @@ impl PluginManager { continue; } } - if let Err(e) = self - .add_plugin_by_dir(window_context, candidate.dir.as_str(), candidate.watch) - .await - { + if let Err(e) = self.add_plugin_by_dir(window_context, candidate.dir.as_str()).await { warn!("Failed to add plugin {} {e:?}", candidate.dir); } } diff --git a/src-tauri/yaak-sync/Cargo.toml b/src-tauri/yaak-sync/Cargo.toml index a5a7afd61..a843fc0a5 100644 --- a/src-tauri/yaak-sync/Cargo.toml +++ b/src-tauri/yaak-sync/Cargo.toml @@ -6,8 +6,8 @@ edition = "2024" publish = false [dependencies] -chrono = { version = "0.4.38", features = ["serde"] } -hex = "0.4.3" +chrono = { workspace = true, features = ["serde"] } +hex = { workspace = true } log = "0.4.22" notify = "8.0.0" serde = { workspace = true, features = ["derive"] } diff --git a/src-tauri/yaak-ws/Cargo.toml b/src-tauri/yaak-ws/Cargo.toml index 0501c742a..cbc06abb1 100644 --- a/src-tauri/yaak-ws/Cargo.toml +++ b/src-tauri/yaak-ws/Cargo.toml @@ -12,7 +12,7 @@ md5 = "0.7.0" serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } tauri = { workspace = true } -thiserror = "2.0.11" +thiserror = { workspace = true } tokio = { workspace = true, features = ["macros", "time", "test-util"] } tokio-tungstenite = { version = "0.26.2", default-features = false, features = ["rustls-tls-native-roots", "connect"] } yaak-http = { workspace = true } diff --git a/src-web/components/GrpcRequestPane.tsx b/src-web/components/GrpcRequestPane.tsx index 0d89533f4..7feb5e583 100644 --- a/src-web/components/GrpcRequestPane.tsx +++ b/src-web/components/GrpcRequestPane.tsx @@ -269,7 +269,7 @@ export function GrpcRequestPane({ label="Request" onChangeValue={setActiveTab} tabs={tabs} - tabListClassName="mt-2 !mb-1.5" + tabListClassName="mt-1 !mb-1.5" > diff --git a/src-web/components/HttpResponsePane.tsx b/src-web/components/HttpResponsePane.tsx index 79ed88b07..348435d3b 100644 --- a/src-web/components/HttpResponsePane.tsx +++ b/src-web/components/HttpResponsePane.tsx @@ -153,7 +153,7 @@ export function HttpResponsePane({ style, className, activeRequestId }: Props) { tabs={tabs} label="Response" className="ml-3 mr-3 mb-3" - tabListClassName="mt-1.5" + tabListClassName="mt-0.5" > diff --git a/src-web/components/ImportDataDialog.tsx b/src-web/components/ImportDataDialog.tsx index aea80d2bf..932db03e5 100644 --- a/src-web/components/ImportDataDialog.tsx +++ b/src-web/components/ImportDataDialog.tsx @@ -11,6 +11,7 @@ interface Props { export function ImportDataDialog({ importData }: Props) { const [isLoading, setIsLoading] = useState(false); const [filePath, setFilePath] = useLocalStorage('importFilePath', null); + return ( diff --git a/src-web/components/Settings/Settings.tsx b/src-web/components/Settings/Settings.tsx index 1629b68a7..127ee197d 100644 --- a/src-web/components/Settings/Settings.tsx +++ b/src-web/components/Settings/Settings.tsx @@ -66,8 +66,10 @@ export default function Settings({ hide }: Props) { )} ({ value, label: capitalize(value) }))} @@ -81,7 +83,7 @@ export default function Settings({ hide }: Props) { - + diff --git a/src-web/components/Settings/SettingsPlugins.tsx b/src-web/components/Settings/SettingsPlugins.tsx index 1447cd1c6..8ffdcf3d1 100644 --- a/src-web/components/Settings/SettingsPlugins.tsx +++ b/src-web/components/Settings/SettingsPlugins.tsx @@ -1,8 +1,11 @@ +import { useMutation, useQuery } from '@tanstack/react-query'; import { openUrl } from '@tauri-apps/plugin-opener'; -import type { Plugin} from '@yaakapp-internal/models'; +import type { Plugin } from '@yaakapp-internal/models'; import { pluginsAtom } from '@yaakapp-internal/models'; +import { installPlugin, PluginVersion, searchPlugins } from '@yaakapp-internal/plugins'; import { useAtomValue } from 'jotai'; -import React from 'react'; +import React, { useState } from 'react'; +import { useDebouncedValue } from '../../hooks/useDebouncedValue'; import { useInstallPlugin } from '../../hooks/useInstallPlugin'; import { usePluginInfo } from '../../hooks/usePluginInfo'; import { useRefreshPlugins } from '../../hooks/usePlugins'; @@ -10,86 +13,86 @@ import { useUninstallPlugin } from '../../hooks/useUninstallPlugin'; import { Button } from '../core/Button'; import { IconButton } from '../core/IconButton'; import { InlineCode } from '../core/InlineCode'; +import { LoadingIcon } from '../core/LoadingIcon'; +import { PlainInput } from '../core/PlainInput'; import { HStack } from '../core/Stacks'; +import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow } from '../core/Table'; +import { TabContent, Tabs } from '../core/Tabs/Tabs'; import { EmptyStateText } from '../EmptyStateText'; import { SelectFile } from '../SelectFile'; export function SettingsPlugins() { const [directory, setDirectory] = React.useState(null); - const plugins = useAtomValue(pluginsAtom); const createPlugin = useInstallPlugin(); const refreshPlugins = useRefreshPlugins(); + const [tab, setTab] = useState(); return ( -
- {plugins.length === 0 ? ( -
- - Plugins extend the functionality of Yaak. -
- Add your first plugin to get started. -
-
- ) : ( - - - - - - - - - - {plugins.map((p) => ( - - ))} - -
PluginVersion
- )} -
{ - e.preventDefault(); - if (directory == null) return; - createPlugin.mutate(directory); - setDirectory(null); - }} +
+ -
- setDirectory(filePath)} - filePath={directory} - /> - - {directory && ( - - )} - refreshPlugins.mutate()} - /> - openUrl('https://feedback.yaak.app/help/articles/6911763-quick-start')} - /> - -
- + + + + + +
{ + e.preventDefault(); + if (directory == null) return; + createPlugin.mutate(directory); + setDirectory(null); + }} + > +
+ setDirectory(filePath)} + filePath={directory} + /> + + {directory && ( + + )} + refreshPlugins.mutate()} + /> + + openUrl('https://feedback.yaak.app/help/articles/6911763-quick-start') + } + /> + +
+
+
+
); } function PluginInfo({ plugin }: { plugin: Plugin }) { const pluginInfo = usePluginInfo(plugin.id); - const deletePlugin = useUninstallPlugin(plugin.id); + const deletePlugin = useUninstallPlugin(); return ( {pluginInfo.data?.name} @@ -101,9 +104,127 @@ function PluginInfo({ plugin }: { plugin: Plugin }) { size="sm" icon="trash" title="Uninstall plugin" - onClick={() => deletePlugin.mutate()} + onClick={() => deletePlugin.mutate(plugin.id)} /> ); } + +function PluginSearch() { + const [query, setQuery] = useState(''); + const debouncedQuery = useDebouncedValue(query); + const results = useQuery({ + queryKey: ['plugins', debouncedQuery], + queryFn: () => searchPlugins(query), + }); + + return ( +
+ + + +
+ {results.data == null ? ( + + + + ) : (results.data.results ?? []).length === 0 ? ( + No plugins found + ) : ( + + + + Name + Version + Description + + + + + {results.data.results.map((plugin) => { + return ( + + {plugin.displayName} + + {plugin.version} + + + {plugin.description ?? 'n/a'} + + + + + + ); + })} + +
+ )} +
+
+ ); +} + +function InstallPluginButton({ plugin }: { plugin: PluginVersion }) { + const plugins = useAtomValue(pluginsAtom); + const deletePlugin = useUninstallPlugin(); + const installed = plugins?.some((p) => p.id === plugin.id); + const installPluginMutation = useMutation({ + mutationKey: ['install_plugin', plugin.id], + mutationFn: installPlugin, + }); + + return ( + + ); +} + +function InstalledPlugins() { + const plugins = useAtomValue(pluginsAtom); + return plugins.length === 0 ? ( +
+ + Plugins extend the functionality of Yaak. +
+ Add your first plugin to get started. +
+
+ ) : ( + + + + + + + + + + {plugins.map((p) => ( + + ))} + +
PluginVersion
+ ); +} diff --git a/src-web/components/SettingsDropdown.tsx b/src-web/components/SettingsDropdown.tsx index 6710cebc7..fc2c14533 100644 --- a/src-web/components/SettingsDropdown.tsx +++ b/src-web/components/SettingsDropdown.tsx @@ -2,12 +2,12 @@ import { openUrl } from '@tauri-apps/plugin-opener'; import { useLicense } from '@yaakapp-internal/license'; import { useRef } from 'react'; import { openSettings } from '../commands/openSettings'; -import { appInfo } from '../lib/appInfo'; import { useCheckForUpdates } from '../hooks/useCheckForUpdates'; import { useExportData } from '../hooks/useExportData'; -import { useImportData } from '../hooks/useImportData'; import { useListenToTauriEvent } from '../hooks/useListenToTauriEvent'; +import { appInfo } from '../lib/appInfo'; import { showDialog } from '../lib/dialog'; +import { importData } from '../lib/importData'; import type { DropdownRef } from './core/Dropdown'; import { Dropdown } from './core/Dropdown'; import { Icon } from './core/Icon'; @@ -15,7 +15,6 @@ import { IconButton } from './core/IconButton'; import { KeyboardShortcutsDialog } from './KeyboardShortcutsDialog'; export function SettingsDropdown() { - const importData = useImportData(); const exportData = useExportData(); const dropdownRef = useRef(null); const checkForUpdates = useCheckForUpdates(); diff --git a/src-web/components/WebsocketRequestPane.tsx b/src-web/components/WebsocketRequestPane.tsx index 959a7cbb1..b2feaada8 100644 --- a/src-web/components/WebsocketRequestPane.tsx +++ b/src-web/components/WebsocketRequestPane.tsx @@ -234,7 +234,7 @@ export function WebsocketRequestPane({ style, fullHeight, className, activeReque label="Request" onChangeValue={setActiveTab} tabs={tabs} - tabListClassName="mt-2 !mb-1.5" + tabListClassName="mt-1 !mb-1.5" > diff --git a/src-web/components/Workspace.tsx b/src-web/components/Workspace.tsx index 7e1a7b72f..d01dae03b 100644 --- a/src-web/components/Workspace.tsx +++ b/src-web/components/Workspace.tsx @@ -4,14 +4,19 @@ import { useAtomValue } from 'jotai'; import * as m from 'motion/react-m'; import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react'; import { useCallback, useMemo, useRef, useState } from 'react'; -import { useEnsureActiveCookieJar, useSubscribeActiveCookieJarId } from '../hooks/useActiveCookieJar'; -import { activeEnvironmentAtom, useSubscribeActiveEnvironmentId } from '../hooks/useActiveEnvironment'; +import { + useEnsureActiveCookieJar, + useSubscribeActiveCookieJarId, +} from '../hooks/useActiveCookieJar'; +import { + activeEnvironmentAtom, + useSubscribeActiveEnvironmentId, +} from '../hooks/useActiveEnvironment'; import { activeRequestAtom } from '../hooks/useActiveRequest'; import { useSubscribeActiveRequestId } from '../hooks/useActiveRequestId'; import { activeWorkspaceAtom } from '../hooks/useActiveWorkspace'; import { useFloatingSidebarHidden } from '../hooks/useFloatingSidebarHidden'; import { useHotKey } from '../hooks/useHotKey'; -import { useImportData } from '../hooks/useImportData'; import { useSubscribeRecentCookieJars } from '../hooks/useRecentCookieJars'; import { useSubscribeRecentEnvironments } from '../hooks/useRecentEnvironments'; import { useSubscribeRecentRequests } from '../hooks/useRecentRequests'; @@ -22,6 +27,7 @@ import { useSidebarWidth } from '../hooks/useSidebarWidth'; import { useSyncWorkspaceRequestTitle } from '../hooks/useSyncWorkspaceRequestTitle'; import { useToggleCommandPalette } from '../hooks/useToggleCommandPalette'; import { duplicateRequestAndNavigate } from '../lib/duplicateRequestAndNavigate'; +import { importData } from '../lib/importData'; import { jotaiStore } from '../lib/jotai'; import { Banner } from './core/Banner'; import { Button } from './core/Button'; @@ -204,7 +210,6 @@ export function Workspace() { function WorkspaceBody() { const activeRequest = useAtomValue(activeRequestAtom); const activeWorkspace = useAtomValue(activeWorkspaceAtom); - const importData = useImportData(); if (activeWorkspace == null) { return ( diff --git a/src-web/components/core/Tabs/Tabs.tsx b/src-web/components/core/Tabs/Tabs.tsx index 001ea59df..274dcd1ae 100644 --- a/src-web/components/core/Tabs/Tabs.tsx +++ b/src-web/components/core/Tabs/Tabs.tsx @@ -1,11 +1,9 @@ import classNames from 'classnames'; import type { ReactNode } from 'react'; import { memo, useEffect, useRef } from 'react'; -import { Icon } from '../Icon'; -import type { RadioDropdownProps } from '../RadioDropdown'; -import { RadioDropdown } from '../RadioDropdown'; -import { HStack } from '../Stacks'; import { ErrorBoundary } from '../../ErrorBoundary'; +import { Icon } from '../Icon'; +import { RadioDropdown, RadioDropdownProps } from '../RadioDropdown'; export type TabItem = | { @@ -28,6 +26,7 @@ interface Props { className?: string; children: ReactNode; addBorders?: boolean; + layout?: 'horizontal' | 'vertical'; } export function Tabs({ @@ -39,6 +38,7 @@ export function Tabs({ className, tabListClassName, addBorders, + layout = 'vertical', }: Props) { const ref = useRef(null); @@ -49,7 +49,10 @@ export function Tabs({ const tabs = ref.current?.querySelectorAll(`[data-tab]`); for (const tab of tabs ?? []) { const v = tab.getAttribute('data-tab'); - if (v === value) { + let parent = tab.closest('.tabs-container'); + if (parent !== ref.current) { + // Tab is part of a nested tab container, so ignore it + } else if (v === value) { tab.setAttribute('tabindex', '-1'); tab.setAttribute('data-state', 'active'); tab.setAttribute('aria-hidden', 'false'); @@ -67,29 +70,41 @@ export function Tabs({ ref={ref} className={classNames( className, + 'tabs-container', 'transform-gpu', - 'h-full grid grid-rows-[auto_minmax(0,1fr)] grid-cols-1', + 'h-full grid', + layout === 'horizontal' && 'grid-rows-1 grid-cols-[auto_minmax(0,1fr)]', + layout === 'vertical' && 'grid-rows-[auto_minmax(0,1fr)] grid-cols-1', )} >
- +
{tabs.map((t) => { const isActive = t.value === value; const btnClassName = classNames( - 'h-full flex items-center rounded', + 'h-sm flex items-center rounded', '!px-2 ml-[1px]', addBorders && 'border', isActive ? 'text-text' : 'text-text-subtle hover:text-text', - isActive && addBorders ? 'border-border-subtle' : 'border-transparent', + isActive && addBorders + ? 'border-border-subtle bg-surface-active' + : 'border-transparent', ); if ('options' in t) { @@ -135,7 +150,7 @@ export function Tabs({ ); } })} - +
{children}
diff --git a/src-web/hooks/useImportData.tsx b/src-web/hooks/useImportData.tsx deleted file mode 100644 index 3d10a3268..000000000 --- a/src-web/hooks/useImportData.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import type { BatchUpsertResult } from '@yaakapp-internal/models'; -import { Button } from '../components/core/Button'; -import { FormattedError } from '../components/core/FormattedError'; -import { VStack } from '../components/core/Stacks'; -import { ImportDataDialog } from '../components/ImportDataDialog'; -import { showAlert } from '../lib/alert'; -import { showDialog } from '../lib/dialog'; -import { jotaiStore } from '../lib/jotai'; -import { pluralizeCount } from '../lib/pluralize'; -import { router } from '../lib/router'; -import { invokeCmd } from '../lib/tauri'; -import { activeWorkspaceAtom } from './useActiveWorkspace'; -import { useFastMutation } from './useFastMutation'; - -export function useImportData() { - const importData = async (filePath: string): Promise => { - const activeWorkspace = jotaiStore.get(activeWorkspaceAtom); - const imported = await invokeCmd('cmd_import_data', { - filePath, - workspaceId: activeWorkspace?.id, - }); - - const importedWorkspace = imported.workspaces[0]; - - showDialog({ - id: 'import-complete', - title: 'Import Complete', - size: 'sm', - hideX: true, - render: ({ hide }) => { - return ( - -
    -
  • {pluralizeCount('Workspace', imported.workspaces.length)}
  • - {imported.environments.length > 0 && ( -
  • {pluralizeCount('Environment', imported.environments.length)}
  • - )} - {imported.folders.length > 0 && ( -
  • {pluralizeCount('Folder', imported.folders.length)}
  • - )} - {imported.httpRequests.length > 0 && ( -
  • {pluralizeCount('HTTP Request', imported.httpRequests.length)}
  • - )} - {imported.grpcRequests.length > 0 && ( -
  • {pluralizeCount('GRPC Request', imported.grpcRequests.length)}
  • - )} - {imported.websocketRequests.length > 0 && ( -
  • {pluralizeCount('Websocket Request', imported.websocketRequests.length)}
  • - )} -
-
- -
-
- ); - }, - }); - - if (importedWorkspace != null) { - const environmentId = imported.environments[0]?.id ?? null; - await router.navigate({ - to: '/workspaces/$workspaceId', - params: { workspaceId: importedWorkspace.id }, - search: { environment_id: environmentId }, - }); - } - - return true; - }; - - return useFastMutation({ - mutationKey: ['import_data'], - onError: (err: string) => { - showAlert({ - id: 'import-failed', - title: 'Import Failed', - size: 'md', - body: {err}, - }); - }, - mutationFn: async () => { - return new Promise((resolve, reject) => { - showDialog({ - id: 'import', - title: 'Import Data', - size: 'sm', - render: ({ hide }) => { - const importAndHide = async (filePath: string) => { - try { - const didImport = await importData(filePath); - if (!didImport) { - return; - } - resolve(); - } catch (err) { - reject(err); - } finally { - hide(); - } - }; - return ; - }, - }); - }); - }, - }); -} diff --git a/src-web/hooks/usePluginInfo.ts b/src-web/hooks/usePluginInfo.ts index f09a601c8..205e858c2 100644 --- a/src-web/hooks/usePluginInfo.ts +++ b/src-web/hooks/usePluginInfo.ts @@ -10,10 +10,7 @@ function pluginInfoKey(id: string) { export function usePluginInfo(id: string) { return useQuery({ queryKey: pluginInfoKey(id), - queryFn: async () => { - const info = (await invokeCmd('cmd_plugin_info', { id })) as BootResponse; - return info; - }, + queryFn: () => invokeCmd('cmd_plugin_info', { id }), }); } diff --git a/src-web/hooks/useUninstallPlugin.ts b/src-web/hooks/useUninstallPlugin.ts index fc34fbb0f..de738e893 100644 --- a/src-web/hooks/useUninstallPlugin.ts +++ b/src-web/hooks/useUninstallPlugin.ts @@ -1,11 +1,10 @@ -import { useFastMutation } from './useFastMutation'; -import type { Plugin } from '@yaakapp-internal/models'; import { invokeCmd } from '../lib/tauri'; +import { useFastMutation } from './useFastMutation'; -export function useUninstallPlugin(pluginId: string) { - return useFastMutation({ +export function useUninstallPlugin() { + return useFastMutation({ mutationKey: ['uninstall_plugin'], - mutationFn: async () => { + mutationFn: async (pluginId: string) => { return invokeCmd('cmd_uninstall_plugin', { pluginId }); }, }); diff --git a/src-web/lib/importData.tsx b/src-web/lib/importData.tsx new file mode 100644 index 000000000..eede8fc2e --- /dev/null +++ b/src-web/lib/importData.tsx @@ -0,0 +1,107 @@ +import type { BatchUpsertResult } from '@yaakapp-internal/models'; +import { Button } from '../components/core/Button'; +import { FormattedError } from '../components/core/FormattedError'; +import { VStack } from '../components/core/Stacks'; +import { ImportDataDialog } from '../components/ImportDataDialog'; +import { activeWorkspaceAtom } from '../hooks/useActiveWorkspace'; +import { createFastMutation } from '../hooks/useFastMutation'; +import { showAlert } from './alert'; +import { showDialog } from './dialog'; +import { jotaiStore } from './jotai'; +import { pluralizeCount } from './pluralize'; +import { router } from './router'; +import { invokeCmd } from './tauri'; + +export const importData = createFastMutation({ + mutationKey: ['import_data'], + onError: (err: string) => { + showAlert({ + id: 'import-failed', + title: 'Import Failed', + size: 'md', + body: {err}, + }); + }, + mutationFn: async () => { + return new Promise((resolve, reject) => { + showDialog({ + id: 'import', + title: 'Import Data', + size: 'sm', + render: ({ hide }) => { + const importAndHide = async (filePath: string) => { + try { + const didImport = await performImport(filePath); + if (!didImport) { + return; + } + resolve(); + } catch (err) { + reject(err); + } finally { + hide(); + } + }; + return ; + }, + }); + }); + }, +}); + +async function performImport(filePath: string): Promise { + const activeWorkspace = jotaiStore.get(activeWorkspaceAtom); + const imported = await invokeCmd('cmd_import_data', { + filePath, + workspaceId: activeWorkspace?.id, + }); + + const importedWorkspace = imported.workspaces[0]; + + showDialog({ + id: 'import-complete', + title: 'Import Complete', + size: 'sm', + hideX: true, + render: ({ hide }) => { + return ( + +
    +
  • {pluralizeCount('Workspace', imported.workspaces.length)}
  • + {imported.environments.length > 0 && ( +
  • {pluralizeCount('Environment', imported.environments.length)}
  • + )} + {imported.folders.length > 0 && ( +
  • {pluralizeCount('Folder', imported.folders.length)}
  • + )} + {imported.httpRequests.length > 0 && ( +
  • {pluralizeCount('HTTP Request', imported.httpRequests.length)}
  • + )} + {imported.grpcRequests.length > 0 && ( +
  • {pluralizeCount('GRPC Request', imported.grpcRequests.length)}
  • + )} + {imported.websocketRequests.length > 0 && ( +
  • {pluralizeCount('Websocket Request', imported.websocketRequests.length)}
  • + )} +
+
+ +
+
+ ); + }, + }); + + if (importedWorkspace != null) { + const environmentId = imported.environments[0]?.id ?? null; + await router.navigate({ + to: '/workspaces/$workspaceId', + params: { workspaceId: importedWorkspace.id }, + search: { environment_id: environmentId }, + }); + } + + return true; +} From cb7c44cc650f296d277ee5fa713d48257068713a Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 23 Jun 2025 08:55:38 -0700 Subject: [PATCH 276/996] Install plugins from Yaak plugin registry (#230) --- .../src/bindings/gen_api.ts | 8 + .../src/bindings/gen_search.ts | 4 +- src-tauri/src/lib.rs | 14 +- src-tauri/src/plugin_events.rs | 14 +- src-tauri/src/uri_scheme.rs | 14 +- src-tauri/yaak-models/src/db_context.rs | 4 +- src-tauri/yaak-models/src/error.rs | 4 +- src-tauri/yaak-models/src/models.rs | 40 ++--- src-tauri/yaak-plugins/bindings/gen_api.ts | 8 + src-tauri/yaak-plugins/bindings/gen_search.ts | 4 +- src-tauri/yaak-plugins/build.rs | 2 +- src-tauri/yaak-plugins/index.ts | 10 +- .../yaak-plugins/permissions/default.toml | 2 +- src-tauri/yaak-plugins/src/api.rs | 77 ++++++++ src-tauri/yaak-plugins/src/commands.rs | 38 ++-- src-tauri/yaak-plugins/src/install.rs | 24 +-- src-tauri/yaak-plugins/src/lib.rs | 5 +- src-tauri/yaak-plugins/src/manager.rs | 18 +- src-tauri/yaak-plugins/src/plugin_handle.rs | 30 ++-- src-tauri/yaak-plugins/src/plugin_meta.rs | 64 +++++++ .../components/Settings/SettingsPlugins.tsx | 167 +++++++++++------- src-web/components/core/Icon.tsx | 3 +- src-web/components/core/IconButton.tsx | 30 ++-- src-web/components/core/Table.tsx | 2 +- src-web/hooks/usePluginInfo.ts | 17 +- src-web/hooks/useUninstallPlugin.ts | 11 -- src-web/hooks/useUninstallPlugin.tsx | 25 +++ 27 files changed, 421 insertions(+), 218 deletions(-) create mode 100644 packages/plugin-runtime-types/src/bindings/gen_api.ts create mode 100644 src-tauri/yaak-plugins/bindings/gen_api.ts create mode 100644 src-tauri/yaak-plugins/src/plugin_meta.rs delete mode 100644 src-web/hooks/useUninstallPlugin.ts create mode 100644 src-web/hooks/useUninstallPlugin.tsx diff --git a/packages/plugin-runtime-types/src/bindings/gen_api.ts b/packages/plugin-runtime-types/src/bindings/gen_api.ts new file mode 100644 index 000000000..d8c88183b --- /dev/null +++ b/packages/plugin-runtime-types/src/bindings/gen_api.ts @@ -0,0 +1,8 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { PluginVersion } from "./gen_search.js"; + +export type PluginNameVersion = { name: string, version: string, }; + +export type PluginSearchResponse = { plugins: Array, }; + +export type PluginUpdatesResponse = { plugins: Array, }; diff --git a/packages/plugin-runtime-types/src/bindings/gen_search.ts b/packages/plugin-runtime-types/src/bindings/gen_search.ts index f0c56473f..9dbe01036 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_search.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_search.ts @@ -1,5 +1,5 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type PluginSearchResponse = { results: Array, }; +export type PluginMetadata = { version: string, name: string, displayName: string, description: string | null, homepageUrl: string | null, repositoryUrl: string | null, }; -export type PluginVersion = { id: string, version: string, description: string | null, displayName: string, homepageUrl: string | null, repositoryUrl: string, checksum: string, readme: string | null, yanked: boolean, }; +export type PluginVersion = { id: string, version: string, description: string | null, name: string, displayName: string, homepageUrl: string | null, repositoryUrl: string | null, checksum: string, readme: string | null, yanked: boolean, }; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 8adeee2c9..8ba4d5eaf 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -36,12 +36,13 @@ use yaak_models::models::{ use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::{BatchUpsertResult, UpdateSource, get_workspace_export_resources}; use yaak_plugins::events::{ - BootResponse, CallHttpRequestActionRequest, FilterResponse, - GetHttpAuthenticationConfigResponse, GetHttpAuthenticationSummaryResponse, - GetHttpRequestActionsResponse, GetTemplateFunctionsResponse, InternalEvent, - InternalEventPayload, JsonPrimitive, PluginWindowContext, RenderPurpose, + CallHttpRequestActionRequest, FilterResponse, GetHttpAuthenticationConfigResponse, + GetHttpAuthenticationSummaryResponse, GetHttpRequestActionsResponse, + GetTemplateFunctionsResponse, InternalEvent, InternalEventPayload, JsonPrimitive, + PluginWindowContext, RenderPurpose, }; use yaak_plugins::manager::PluginManager; +use yaak_plugins::plugin_meta::PluginMetadata; use yaak_plugins::template_callback::PluginTemplateCallback; use yaak_sse::sse::ServerSentEvent; use yaak_templates::format::format_json; @@ -1039,14 +1040,13 @@ async fn cmd_plugin_info( id: &str, app_handle: AppHandle, plugin_manager: State<'_, PluginManager>, -) -> YaakResult { +) -> YaakResult { let plugin = app_handle.db().get_plugin(id)?; Ok(plugin_manager .get_plugin_by_dir(plugin.directory.as_str()) .await .ok_or(GenericError("Failed to find plugin for info".to_string()))? - .info() - .await) + .info()) } #[tauri::command] diff --git a/src-tauri/src/plugin_events.rs b/src-tauri/src/plugin_events.rs index 9ebac1db9..bcb136c43 100644 --- a/src-tauri/src/plugin_events.rs +++ b/src-tauri/src/plugin_events.rs @@ -86,8 +86,8 @@ pub(crate) async fn handle_plugin_event( environment.as_ref(), &cb, ) - .await - .expect("Failed to render http request"); + .await + .expect("Failed to render http request"); Some(InternalEventPayload::RenderHttpRequestResponse(RenderHttpRequestResponse { http_request, })) @@ -115,7 +115,7 @@ pub(crate) async fn handle_plugin_event( &InternalEventPayload::ShowToastRequest(ShowToastRequest { message: format!( "Plugin error from {}: {}", - plugin_handle.name().await, + plugin_handle.info().name, resp.error ), color: Some(Color::Danger), @@ -188,7 +188,7 @@ pub(crate) async fn handle_plugin_event( cookie_jar, &mut tokio::sync::watch::channel(false).1, // No-op cancel channel ) - .await; + .await; let http_response = match result { Ok(r) => r, @@ -257,17 +257,17 @@ pub(crate) async fn handle_plugin_event( None } InternalEventPayload::SetKeyValueRequest(req) => { - let name = plugin_handle.name().await; + let name = plugin_handle.info().name; app_handle.db().set_plugin_key_value(&name, &req.key, &req.value); Some(InternalEventPayload::SetKeyValueResponse(SetKeyValueResponse {})) } InternalEventPayload::GetKeyValueRequest(req) => { - let name = plugin_handle.name().await; + let name = plugin_handle.info().name; let value = app_handle.db().get_plugin_key_value(&name, &req.key).map(|v| v.value); Some(InternalEventPayload::GetKeyValueResponse(GetKeyValueResponse { value })) } InternalEventPayload::DeleteKeyValueRequest(req) => { - let name = plugin_handle.name().await; + let name = plugin_handle.info().name; let deleted = app_handle.db().delete_plugin_key_value(&name, &req.key).unwrap(); Some(InternalEventPayload::DeleteKeyValueResponse(DeleteKeyValueResponse { deleted })) } diff --git a/src-tauri/src/uri_scheme.rs b/src-tauri/src/uri_scheme.rs index eff526967..e3a201cbd 100644 --- a/src-tauri/src/uri_scheme.rs +++ b/src-tauri/src/uri_scheme.rs @@ -4,7 +4,6 @@ use log::{info, warn}; use std::collections::HashMap; use tauri::{AppHandle, Emitter, Manager, Runtime, Url}; use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogKind}; -use yaak_plugins::api::get_plugin; use yaak_plugins::events::{Color, ShowToastRequest}; use yaak_plugins::install::download_and_install; @@ -23,14 +22,10 @@ pub(crate) async fn handle_deep_link( "install-plugin" => { let name = query_map.get("name").unwrap(); let version = query_map.get("version").cloned(); - let plugin_version = get_plugin(&app_handle, &name, version).await?; _ = window.set_focus(); let confirmed_install = app_handle .dialog() - .message(format!( - "Install plugin {}@{}?", - plugin_version.name, plugin_version.version - )) + .message(format!("Install plugin {name} {version:?}?",)) .kind(MessageDialogKind::Info) .buttons(MessageDialogButtons::OkCustom("Install".to_string())) .blocking_show(); @@ -39,14 +34,11 @@ pub(crate) async fn handle_deep_link( return Ok(()); } - download_and_install(window, &plugin_version).await?; + let pv = download_and_install(window, name, version).await?; app_handle.emit( "show_toast", ShowToastRequest { - message: format!( - "Installed {}@{}", - plugin_version.name, plugin_version.version - ), + message: format!("Installed {name}@{}", pv.version), color: Some(Color::Success), icon: None, }, diff --git a/src-tauri/yaak-models/src/db_context.rs b/src-tauri/yaak-models/src/db_context.rs index f16000d50..04bb25527 100644 --- a/src-tauri/yaak-models/src/db_context.rs +++ b/src-tauri/yaak-models/src/db_context.rs @@ -1,5 +1,5 @@ use crate::connection_or_tx::ConnectionOrTx; -use crate::error::Error::RowNotFound; +use crate::error::Error::DBRowNotFound; use crate::models::{AnyModel, UpsertModelInfo}; use crate::util::{ModelChangeEvent, ModelPayload, UpdateSource}; use rusqlite::OptionalExtension; @@ -26,7 +26,7 @@ impl<'a> DbContext<'a> { { match self.find_optional::(col, value) { Some(v) => Ok(v), - None => Err(RowNotFound), + None => Err(DBRowNotFound(format!("{:?}", M::table_name()))), } } diff --git a/src-tauri/yaak-models/src/error.rs b/src-tauri/yaak-models/src/error.rs index b7cc70507..d64ff9d20 100644 --- a/src-tauri/yaak-models/src/error.rs +++ b/src-tauri/yaak-models/src/error.rs @@ -30,8 +30,8 @@ pub enum Error { #[error("Multiple base environments for {0}. Delete duplicates before continuing.")] MultipleBaseEnvironments(String), - #[error("Row not found")] - RowNotFound, + #[error("Database row not found: {0}")] + DBRowNotFound(String), #[error("unknown error")] Unknown, diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index 4581646e7..623fe815f 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -11,7 +11,7 @@ use sea_query::{IntoColumnRef, IntoIden, IntoTableRef, Order, SimpleExpr, enum_d use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value; use std::collections::BTreeMap; -use std::fmt::Display; +use std::fmt::{Debug, Display}; use std::str::FromStr; use ts_rs::TS; @@ -123,7 +123,7 @@ pub struct Settings { } impl UpsertModelInfo for Settings { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { SettingsIden::Table } @@ -252,7 +252,7 @@ pub struct Workspace { } impl UpsertModelInfo for Workspace { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { WorkspaceIden::Table } @@ -355,7 +355,7 @@ pub struct WorkspaceMeta { } impl UpsertModelInfo for WorkspaceMeta { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { WorkspaceMetaIden::Table } @@ -456,7 +456,7 @@ pub struct CookieJar { } impl UpsertModelInfo for CookieJar { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { CookieJarIden::Table } @@ -535,7 +535,7 @@ pub struct Environment { } impl UpsertModelInfo for Environment { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { EnvironmentIden::Table } @@ -655,7 +655,7 @@ pub struct Folder { } impl UpsertModelInfo for Folder { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { FolderIden::Table } @@ -786,7 +786,7 @@ pub struct HttpRequest { } impl UpsertModelInfo for HttpRequest { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { HttpRequestIden::Table } @@ -913,7 +913,7 @@ pub struct WebsocketConnection { } impl UpsertModelInfo for WebsocketConnection { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { WebsocketConnectionIden::Table } @@ -1027,7 +1027,7 @@ pub struct WebsocketRequest { } impl UpsertModelInfo for WebsocketRequest { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { WebsocketRequestIden::Table } @@ -1152,7 +1152,7 @@ pub struct WebsocketEvent { } impl UpsertModelInfo for WebsocketEvent { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { WebsocketEventIden::Table } @@ -1269,7 +1269,7 @@ pub struct HttpResponse { } impl UpsertModelInfo for HttpResponse { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { HttpResponseIden::Table } @@ -1377,7 +1377,7 @@ pub struct GraphQlIntrospection { } impl UpsertModelInfo for GraphQlIntrospection { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { GraphQlIntrospectionIden::Table } @@ -1461,7 +1461,7 @@ pub struct GrpcRequest { } impl UpsertModelInfo for GrpcRequest { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { GrpcRequestIden::Table } @@ -1588,7 +1588,7 @@ pub struct GrpcConnection { } impl UpsertModelInfo for GrpcConnection { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { GrpcConnectionIden::Table } @@ -1708,7 +1708,7 @@ pub struct GrpcEvent { } impl UpsertModelInfo for GrpcEvent { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { GrpcEventIden::Table } @@ -1799,7 +1799,7 @@ pub struct Plugin { } impl UpsertModelInfo for Plugin { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { PluginIden::Table } @@ -1881,7 +1881,7 @@ pub struct SyncState { } impl UpsertModelInfo for SyncState { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { SyncStateIden::Table } @@ -1964,7 +1964,7 @@ pub struct KeyValue { } impl UpsertModelInfo for KeyValue { - fn table_name() -> impl IntoTableRef { + fn table_name() -> impl IntoTableRef + Debug { KeyValueIden::Table } @@ -2181,7 +2181,7 @@ impl AnyModel { } pub trait UpsertModelInfo { - fn table_name() -> impl IntoTableRef; + fn table_name() -> impl IntoTableRef + Debug; fn id_column() -> impl IntoIden + Eq + Clone; fn generate_id() -> String; fn order_by() -> (impl IntoColumnRef, Order); diff --git a/src-tauri/yaak-plugins/bindings/gen_api.ts b/src-tauri/yaak-plugins/bindings/gen_api.ts new file mode 100644 index 000000000..d8c88183b --- /dev/null +++ b/src-tauri/yaak-plugins/bindings/gen_api.ts @@ -0,0 +1,8 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { PluginVersion } from "./gen_search.js"; + +export type PluginNameVersion = { name: string, version: string, }; + +export type PluginSearchResponse = { plugins: Array, }; + +export type PluginUpdatesResponse = { plugins: Array, }; diff --git a/src-tauri/yaak-plugins/bindings/gen_search.ts b/src-tauri/yaak-plugins/bindings/gen_search.ts index f0c56473f..9dbe01036 100644 --- a/src-tauri/yaak-plugins/bindings/gen_search.ts +++ b/src-tauri/yaak-plugins/bindings/gen_search.ts @@ -1,5 +1,5 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type PluginSearchResponse = { results: Array, }; +export type PluginMetadata = { version: string, name: string, displayName: string, description: string | null, homepageUrl: string | null, repositoryUrl: string | null, }; -export type PluginVersion = { id: string, version: string, description: string | null, displayName: string, homepageUrl: string | null, repositoryUrl: string, checksum: string, readme: string | null, yanked: boolean, }; +export type PluginVersion = { id: string, version: string, description: string | null, name: string, displayName: string, homepageUrl: string | null, repositoryUrl: string | null, checksum: string, readme: string | null, yanked: boolean, }; diff --git a/src-tauri/yaak-plugins/build.rs b/src-tauri/yaak-plugins/build.rs index 88527efaf..7a8b73a3f 100644 --- a/src-tauri/yaak-plugins/build.rs +++ b/src-tauri/yaak-plugins/build.rs @@ -1,4 +1,4 @@ -const COMMANDS: &[&str] = &["search", "install"]; +const COMMANDS: &[&str] = &["search", "install", "updates"]; fn main() { tauri_plugin::Builder::new(COMMANDS).build(); diff --git a/src-tauri/yaak-plugins/index.ts b/src-tauri/yaak-plugins/index.ts index 10ec0c898..2b1471635 100644 --- a/src-tauri/yaak-plugins/index.ts +++ b/src-tauri/yaak-plugins/index.ts @@ -1,5 +1,5 @@ import { invoke } from '@tauri-apps/api/core'; -import { PluginSearchResponse, PluginVersion } from './bindings/gen_search'; +import { PluginSearchResponse, PluginUpdatesResponse } from './bindings/gen_api'; export * from './bindings/gen_models'; export * from './bindings/gen_events'; @@ -9,6 +9,10 @@ export async function searchPlugins(query: string) { return invoke('plugin:yaak-plugins|search', { query }); } -export async function installPlugin(plugin: PluginVersion) { - return invoke('plugin:yaak-plugins|install', { plugin }); +export async function installPlugin(name: string, version: string | null) { + return invoke('plugin:yaak-plugins|install', { name, version }); +} + +export async function checkPluginUpdates() { + return invoke('plugin:yaak-plugins|updates', {}); } diff --git a/src-tauri/yaak-plugins/permissions/default.toml b/src-tauri/yaak-plugins/permissions/default.toml index 054af4e37..7a3aea269 100644 --- a/src-tauri/yaak-plugins/permissions/default.toml +++ b/src-tauri/yaak-plugins/permissions/default.toml @@ -1,3 +1,3 @@ [default] description = "Default permissions for the plugin" -permissions = ["allow-search", "allow-install"] +permissions = ["allow-search", "allow-install", "allow-updates"] diff --git a/src-tauri/yaak-plugins/src/api.rs b/src-tauri/yaak-plugins/src/api.rs index 26e63463f..e8aa95ab6 100644 --- a/src-tauri/yaak-plugins/src/api.rs +++ b/src-tauri/yaak-plugins/src/api.rs @@ -1,10 +1,17 @@ +use crate::error::Error::ApiErr; use crate::commands::{PluginSearchResponse, PluginVersion}; use crate::error::Result; +use crate::plugin_meta::get_plugin_meta; +use log::{info, warn}; use reqwest::{Response, Url}; +use serde::{Deserialize, Serialize}; +use std::path::Path; use std::str::FromStr; use log::info; use tauri::{AppHandle, Runtime, is_dev}; +use ts_rs::TS; use yaak_common::api_client::yaak_api_client; +use yaak_models::query_manager::QueryManagerExt; use crate::error::Error::ApiErr; pub async fn get_plugin( @@ -44,6 +51,38 @@ pub async fn download_plugin_archive( Ok(resp) } +pub async fn check_plugin_updates( + app_handle: &AppHandle, +) -> Result { + let name_versions: Vec = app_handle + .db() + .list_plugins()? + .into_iter() + .filter_map(|p| match get_plugin_meta(&Path::new(&p.directory)) { + Ok(m) => Some(PluginNameVersion { + name: m.name, + version: m.version, + }), + Err(e) => { + warn!("Failed to get plugin metadata: {}", e); + None + } + }) + .collect(); + + let url = base_url("/updates"); + let body = serde_json::to_vec(&PluginUpdatesResponse { + plugins: name_versions, + })?; + let resp = yaak_api_client(app_handle)?.post(url.clone()).body(body).send().await?; + if !resp.status().is_success() { + return Err(ApiErr(format!("{} response to {}", resp.status(), url.to_string()))); + } + + let results: PluginUpdatesResponse = resp.json().await?; + Ok(results) +} + pub async fn search_plugins( app_handle: &AppHandle, query: &str, @@ -65,3 +104,41 @@ fn base_url(path: &str) -> Url { }; Url::from_str(&format!("{base_url}{path}")).unwrap() } + +#[derive(Debug, Clone, Serialize, Deserialize, TS, PartialEq)] +#[serde(rename_all = "camelCase")] +#[ts(export, export_to = "gen_search.ts")] +pub struct PluginVersion { + pub id: String, + pub version: String, + pub description: Option, + pub name: String, + pub display_name: String, + pub homepage_url: Option, + pub repository_url: Option, + pub checksum: String, + pub readme: Option, + pub yanked: bool, +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS, PartialEq)] +#[serde(rename_all = "camelCase")] +#[ts(export, export_to = "gen_api.ts")] +pub struct PluginSearchResponse { + pub plugins: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS, PartialEq)] +#[serde(rename_all = "camelCase")] +#[ts(export, export_to = "gen_api.ts")] +pub struct PluginNameVersion { + name: String, + version: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS, PartialEq)] +#[serde(rename_all = "camelCase")] +#[ts(export, export_to = "gen_api.ts")] +pub struct PluginUpdatesResponse { + pub plugins: Vec, +} diff --git a/src-tauri/yaak-plugins/src/commands.rs b/src-tauri/yaak-plugins/src/commands.rs index 460f3671e..2b06660fe 100644 --- a/src-tauri/yaak-plugins/src/commands.rs +++ b/src-tauri/yaak-plugins/src/commands.rs @@ -1,9 +1,9 @@ -use crate::api::search_plugins; +use crate::api::{ + PluginSearchResponse, PluginUpdatesResponse, check_plugin_updates, search_plugins, +}; use crate::error::Result; use crate::install::download_and_install; -use serde::{Deserialize, Serialize}; use tauri::{AppHandle, Runtime, WebviewWindow, command}; -use ts_rs::TS; #[command] pub(crate) async fn search( @@ -16,30 +16,14 @@ pub(crate) async fn search( #[command] pub(crate) async fn install( window: WebviewWindow, - plugin: PluginVersion, -) -> Result { - download_and_install(&window, &plugin).await + name: &str, + version: Option, +) -> Result<()> { + download_and_install(&window, name, version).await?; + Ok(()) } -#[derive(Debug, Clone, Serialize, Deserialize, TS, PartialEq)] -#[serde(rename_all = "camelCase")] -#[ts(export, export_to = "gen_search.ts")] -pub struct PluginSearchResponse { - pub results: Vec, -} - -#[derive(Debug, Clone, Serialize, Deserialize, TS, PartialEq)] -#[serde(rename_all = "camelCase")] -#[ts(export, export_to = "gen_search.ts")] -pub struct PluginVersion { - pub id: String, - pub version: String, - pub description: Option, - pub name: String, - pub display_name: String, - pub homepage_url: Option, - pub repository_url: Option, - pub checksum: String, - pub readme: Option, - pub yanked: bool, +#[command] +pub(crate) async fn updates(app_handle: AppHandle) -> Result { + check_plugin_updates(&app_handle).await } diff --git a/src-tauri/yaak-plugins/src/install.rs b/src-tauri/yaak-plugins/src/install.rs index e1146263e..105e9a085 100644 --- a/src-tauri/yaak-plugins/src/install.rs +++ b/src-tauri/yaak-plugins/src/install.rs @@ -1,23 +1,25 @@ -use crate::api::download_plugin_archive; +use crate::api::{PluginVersion, download_plugin_archive, get_plugin}; use crate::checksum::compute_checksum; -use crate::commands::PluginVersion; use crate::error::Error::PluginErr; use crate::error::Result; use crate::events::PluginWindowContext; use crate::manager::PluginManager; use chrono::Utc; use log::info; -use std::fs::create_dir_all; +use std::fs::{create_dir_all, remove_dir_all}; use std::io::Cursor; use tauri::{Manager, Runtime, WebviewWindow}; use yaak_models::models::Plugin; use yaak_models::query_manager::QueryManagerExt; -use yaak_models::util::{UpdateSource, generate_id}; +use yaak_models::util::UpdateSource; pub async fn download_and_install( window: &WebviewWindow, - plugin_version: &PluginVersion, -) -> Result { + name: &str, + version: Option, +) -> Result { + let plugin_manager = window.state::(); + let plugin_version = get_plugin(window.app_handle(), name, version).await?; let resp = download_plugin_archive(window.app_handle(), &plugin_version).await?; let bytes = resp.bytes().await?; @@ -32,17 +34,19 @@ pub async fn download_and_install( info!("Checksum matched {}", checksum); - let plugin_dir = window.path().app_data_dir()?.join("plugins").join(generate_id()); + let plugin_dir = plugin_manager.installed_plugin_dir.join(name); let plugin_dir_str = plugin_dir.to_str().unwrap().to_string(); + + // Re-create the plugin directory + let _ = remove_dir_all(&plugin_dir); create_dir_all(&plugin_dir)?; zip_extract::extract(Cursor::new(&bytes), &plugin_dir, true)?; info!("Extracted plugin {} to {}", plugin_version.id, plugin_dir_str); - let plugin_manager = window.state::(); plugin_manager.add_plugin_by_dir(&PluginWindowContext::new(&window), &plugin_dir_str).await?; - let p = window.db().upsert_plugin( + window.db().upsert_plugin( &Plugin { id: plugin_version.id.clone(), checked_at: Some(Utc::now().naive_utc()), @@ -56,5 +60,5 @@ pub async fn download_and_install( info!("Installed plugin {} to {}", plugin_version.id, plugin_dir_str); - Ok(p.id) + Ok(plugin_version) } diff --git a/src-tauri/yaak-plugins/src/lib.rs b/src-tauri/yaak-plugins/src/lib.rs index 960b3dd56..abb821c72 100644 --- a/src-tauri/yaak-plugins/src/lib.rs +++ b/src-tauri/yaak-plugins/src/lib.rs @@ -1,4 +1,4 @@ -use crate::commands::{install, search}; +use crate::commands::{install, search, updates}; use crate::manager::PluginManager; use log::info; use std::process::exit; @@ -18,10 +18,11 @@ mod util; mod checksum; pub mod api; pub mod install; +pub mod plugin_meta; pub fn init() -> TauriPlugin { Builder::new("yaak-plugins") - .invoke_handler(generate_handler![search, install]) + .invoke_handler(generate_handler![search, install, updates]) .setup(|app_handle, _| { let manager = PluginManager::new(app_handle.clone()); app_handle.manage(manager.clone()); diff --git a/src-tauri/yaak-plugins/src/manager.rs b/src-tauri/yaak-plugins/src/manager.rs index 4bec172af..516ddc496 100644 --- a/src-tauri/yaak-plugins/src/manager.rs +++ b/src-tauri/yaak-plugins/src/manager.rs @@ -39,7 +39,7 @@ pub struct PluginManager { kill_tx: tokio::sync::watch::Sender, ws_service: Arc, vendored_plugin_dir: PathBuf, - installed_plugin_dir: PathBuf, + pub(crate) installed_plugin_dir: PathBuf, } #[derive(Clone)] @@ -62,8 +62,11 @@ impl PluginManager { .resolve("vendored/plugins", BaseDirectory::Resource) .expect("failed to resolve plugin directory resource"); - let installed_plugin_dir = - app_handle.path().app_data_dir().expect("failed to get app data dir"); + let installed_plugin_dir = app_handle + .path() + .app_data_dir() + .expect("failed to get app data dir") + .join("installed-plugins"); let plugin_manager = PluginManager { plugins: Default::default(), @@ -209,7 +212,7 @@ impl PluginManager { None => return Err(ClientNotInitializedErr), Some(tx) => tx, }; - let plugin_handle = PluginHandle::new(dir, tx.clone()); + let plugin_handle = PluginHandle::new(dir, tx.clone())?; let dir_path = Path::new(dir); let is_vendored = dir_path.starts_with(self.vendored_plugin_dir.as_path()); let is_installed = dir_path.starts_with(self.installed_plugin_dir.as_path()); @@ -231,14 +234,11 @@ impl PluginManager { // Add the new plugin self.plugins.lock().await.push(plugin_handle.clone()); - let resp = match event.payload { + let _ = match event.payload { InternalEventPayload::BootResponse(resp) => resp, _ => return Err(UnknownEventErr), }; - // Set the boot response - plugin_handle.set_boot_response(&resp).await; - Ok(()) } @@ -317,7 +317,7 @@ impl PluginManager { pub async fn get_plugin_by_name(&self, name: &str) -> Option { for plugin in self.plugins.lock().await.iter().cloned() { - let info = plugin.info().await; + let info = plugin.info(); if info.name == name { return Some(plugin); } diff --git a/src-tauri/yaak-plugins/src/plugin_handle.rs b/src-tauri/yaak-plugins/src/plugin_handle.rs index b35745700..6d6a9262e 100644 --- a/src-tauri/yaak-plugins/src/plugin_handle.rs +++ b/src-tauri/yaak-plugins/src/plugin_handle.rs @@ -1,38 +1,35 @@ use crate::error::Result; -use crate::events::{BootResponse, InternalEvent, InternalEventPayload, PluginWindowContext}; +use crate::events::{InternalEvent, InternalEventPayload, PluginWindowContext}; +use crate::plugin_meta::{PluginMetadata, get_plugin_meta}; use crate::util::gen_id; use log::info; use std::path::Path; use std::sync::Arc; -use tokio::sync::{mpsc, Mutex}; +use tokio::sync::{Mutex, mpsc}; #[derive(Clone)] pub struct PluginHandle { pub ref_id: String, pub dir: String, pub(crate) to_plugin_tx: Arc>>, - pub(crate) boot_resp: Arc>, + pub(crate) metadata: PluginMetadata, } impl PluginHandle { - pub fn new(dir: &str, tx: mpsc::Sender) -> Self { + pub fn new(dir: &str, tx: mpsc::Sender) -> Result { let ref_id = gen_id(); + let metadata = get_plugin_meta(&Path::new(dir))?; - PluginHandle { + Ok(PluginHandle { ref_id: ref_id.clone(), dir: dir.to_string(), to_plugin_tx: Arc::new(Mutex::new(tx)), - boot_resp: Arc::new(Mutex::new(BootResponse::default())), - } - } - - pub async fn name(&self) -> String { - self.boot_resp.lock().await.name.clone() + metadata, + }) } - pub async fn info(&self) -> BootResponse { - let resp = &*self.boot_resp.lock().await; - resp.clone() + pub fn info(&self) -> PluginMetadata { + self.metadata.clone() } pub fn build_event_to_send( @@ -72,9 +69,4 @@ impl PluginHandle { self.to_plugin_tx.lock().await.send(event.to_owned()).await?; Ok(()) } - - pub async fn set_boot_response(&self, resp: &BootResponse) { - let mut boot_resp = self.boot_resp.lock().await; - *boot_resp = resp.clone(); - } } diff --git a/src-tauri/yaak-plugins/src/plugin_meta.rs b/src-tauri/yaak-plugins/src/plugin_meta.rs new file mode 100644 index 000000000..5dd2549e2 --- /dev/null +++ b/src-tauri/yaak-plugins/src/plugin_meta.rs @@ -0,0 +1,64 @@ +use crate::error::Result; +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::Path; +use ts_rs::TS; + +#[derive(Debug, Clone, Serialize, Deserialize, TS, PartialEq)] +#[serde(rename_all = "camelCase")] +#[ts(export, export_to = "gen_search.ts")] +pub struct PluginMetadata { + pub version: String, + pub name: String, + pub display_name: String, + pub description: Option, + pub homepage_url: Option, + pub repository_url: Option, +} + +pub(crate) fn get_plugin_meta(plugin_dir: &Path) -> Result { + let package_json = fs::File::open(plugin_dir.join("package.json"))?; + let package_json: PackageJson = serde_json::from_reader(package_json)?; + + let display_name = match package_json.display_name { + None => { + let display_name = package_json.name.to_string(); + let display_name = display_name.split('/').last().unwrap_or(&package_json.name); + let display_name = display_name.strip_prefix("yaak-plugin-").unwrap_or(&display_name); + let display_name = display_name.strip_prefix("yaak-").unwrap_or(&display_name); + display_name.to_string() + } + Some(n) => n, + }; + + Ok(PluginMetadata { + version: package_json.version, + description: package_json.description, + name: package_json.name, + display_name, + homepage_url: package_json.homepage, + repository_url: match package_json.repository { + None => None, + Some(RepositoryField::Object { url }) => Some(url), + Some(RepositoryField::String(url)) => Some(url), + }, + }) +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct PackageJson { + pub name: String, + pub display_name: Option, + pub version: String, + pub repository: Option, + pub homepage: Option, + pub description: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(untagged)] +enum RepositoryField { + String(String), + Object { url: String }, +} diff --git a/src-web/components/Settings/SettingsPlugins.tsx b/src-web/components/Settings/SettingsPlugins.tsx index 8ffdcf3d1..37b0d4bef 100644 --- a/src-web/components/Settings/SettingsPlugins.tsx +++ b/src-web/components/Settings/SettingsPlugins.tsx @@ -1,8 +1,13 @@ import { useMutation, useQuery } from '@tanstack/react-query'; import { openUrl } from '@tauri-apps/plugin-opener'; -import type { Plugin } from '@yaakapp-internal/models'; -import { pluginsAtom } from '@yaakapp-internal/models'; -import { installPlugin, PluginVersion, searchPlugins } from '@yaakapp-internal/plugins'; +import { Plugin, pluginsAtom } from '@yaakapp-internal/models'; +import { + checkPluginUpdates, + installPlugin, + PluginVersion, + searchPlugins, +} from '@yaakapp-internal/plugins'; +import { PluginUpdatesResponse } from '@yaakapp-internal/plugins/bindings/gen_api'; import { useAtomValue } from 'jotai'; import React, { useState } from 'react'; import { useDebouncedValue } from '../../hooks/useDebouncedValue'; @@ -43,15 +48,8 @@ export function SettingsPlugins() {
- -
{ - e.preventDefault(); - if (directory == null) return; - createPlugin.mutate(directory); - setDirectory(null); - }} - > +
+
{directory && ( - )} @@ -83,31 +90,61 @@ export function SettingsPlugins() { />
- +
); } -function PluginInfo({ plugin }: { plugin: Plugin }) { +function PluginTableRow({ + plugin, + updates, +}: { + plugin: Plugin; + updates: PluginUpdatesResponse | null; +}) { const pluginInfo = usePluginInfo(plugin.id); - const deletePlugin = useUninstallPlugin(); + const uninstallPlugin = useUninstallPlugin(); + const latestVersion = updates?.plugins.find((u) => u.name === pluginInfo.data?.name)?.version; + const installPluginMutation = useMutation({ + mutationKey: ['install_plugin', plugin.id], + mutationFn: (name: string) => installPlugin(name, null), + }); + if (pluginInfo.data == null) return null; + return ( - - {pluginInfo.data?.name} - + + {pluginInfo.data.displayName} + {pluginInfo.data?.version} - - - deletePlugin.mutate(plugin.id)} - /> - - + + {pluginInfo.data.description} + + + {latestVersion != null && ( + + )} + { + uninstallPlugin.mutate({ pluginId: plugin.id, name: pluginInfo.data.displayName }); + }} + /> + + + ); } @@ -135,7 +172,7 @@ function PluginSearch() { - ) : (results.data.results ?? []).length === 0 ? ( + ) : (results.data.plugins ?? []).length === 0 ? ( No plugins found ) : ( @@ -148,22 +185,20 @@ function PluginSearch() { - {results.data.results.map((plugin) => { - return ( - - {plugin.displayName} - - {plugin.version} - - - {plugin.description ?? 'n/a'} - - - - - - ); - })} + {results.data.plugins.map((plugin) => ( + + {plugin.displayName} + + {plugin.version} + + + {plugin.description ?? 'n/a'} + + + + + + ))}
)} @@ -174,23 +209,23 @@ function PluginSearch() { function InstallPluginButton({ plugin }: { plugin: PluginVersion }) { const plugins = useAtomValue(pluginsAtom); - const deletePlugin = useUninstallPlugin(); + const uninstallPlugin = useUninstallPlugin(); const installed = plugins?.some((p) => p.id === plugin.id); const installPluginMutation = useMutation({ mutationKey: ['install_plugin', plugin.id], - mutationFn: installPlugin, + mutationFn: (pv: PluginVersion) => installPlugin(pv.name, null), }); return ( ); }); diff --git a/src-web/components/core/Table.tsx b/src-web/components/core/Table.tsx index 55099a663..ff9e6f3c9 100644 --- a/src-web/components/core/Table.tsx +++ b/src-web/components/core/Table.tsx @@ -53,7 +53,7 @@ export function TableHeaderCell({ children, className, }: { - children: ReactNode; + children?: ReactNode; className?: string; }) { return ( diff --git a/src-web/hooks/usePluginInfo.ts b/src-web/hooks/usePluginInfo.ts index 205e858c2..0ae2a618a 100644 --- a/src-web/hooks/usePluginInfo.ts +++ b/src-web/hooks/usePluginInfo.ts @@ -1,16 +1,23 @@ import { useQuery } from '@tanstack/react-query'; -import type { BootResponse } from '@yaakapp-internal/plugins'; +import type { Plugin } from '@yaakapp-internal/models'; +import { pluginsAtom } from '@yaakapp-internal/models'; +import type { PluginMetadata } from '@yaakapp-internal/plugins'; +import { useAtomValue } from 'jotai'; import { queryClient } from '../lib/queryClient'; import { invokeCmd } from '../lib/tauri'; -function pluginInfoKey(id: string) { - return ['plugin_info', id]; +function pluginInfoKey(id: string, plugin: Plugin | null) { + return ['plugin_info', id, plugin?.updatedAt ?? 'n/a']; } export function usePluginInfo(id: string) { + const plugins = useAtomValue(pluginsAtom); + // Get the plugin so we can refetch whenever it's updated + const plugin = plugins.find((p) => p.id === id); return useQuery({ - queryKey: pluginInfoKey(id), - queryFn: () => invokeCmd('cmd_plugin_info', { id }), + queryKey: pluginInfoKey(id, plugin ?? null), + placeholderData: (prev) => prev, // Keep previous data on refetch + queryFn: () => invokeCmd('cmd_plugin_info', { id }), }); } diff --git a/src-web/hooks/useUninstallPlugin.ts b/src-web/hooks/useUninstallPlugin.ts deleted file mode 100644 index de738e893..000000000 --- a/src-web/hooks/useUninstallPlugin.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { invokeCmd } from '../lib/tauri'; -import { useFastMutation } from './useFastMutation'; - -export function useUninstallPlugin() { - return useFastMutation({ - mutationKey: ['uninstall_plugin'], - mutationFn: async (pluginId: string) => { - return invokeCmd('cmd_uninstall_plugin', { pluginId }); - }, - }); -} diff --git a/src-web/hooks/useUninstallPlugin.tsx b/src-web/hooks/useUninstallPlugin.tsx new file mode 100644 index 000000000..ebbbc9aae --- /dev/null +++ b/src-web/hooks/useUninstallPlugin.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { InlineCode } from '../components/core/InlineCode'; +import { showConfirmDelete } from '../lib/confirm'; +import { invokeCmd } from '../lib/tauri'; +import { useFastMutation } from './useFastMutation'; + +export function useUninstallPlugin() { + return useFastMutation({ + mutationKey: ['uninstall_plugin'], + mutationFn: async ({ pluginId, name }: { pluginId: string; name: string }) => { + const confirmed = await showConfirmDelete({ + id: 'uninstall-plugin-' + name, + title: 'Uninstall Plugin', + description: ( + <> + Permanently uninstall {name}? + + ), + }); + if (confirmed) { + await invokeCmd('cmd_uninstall_plugin', { pluginId }); + } + }, + }); +} From 1948fb78bd8e55b23be15f211d1f6f6136a603f0 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 23 Jun 2025 08:57:31 -0700 Subject: [PATCH 277/996] Fix bad import --- src-tauri/yaak-plugins/src/api.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src-tauri/yaak-plugins/src/api.rs b/src-tauri/yaak-plugins/src/api.rs index e8aa95ab6..ba64d258b 100644 --- a/src-tauri/yaak-plugins/src/api.rs +++ b/src-tauri/yaak-plugins/src/api.rs @@ -1,5 +1,3 @@ -use crate::error::Error::ApiErr; -use crate::commands::{PluginSearchResponse, PluginVersion}; use crate::error::Result; use crate::plugin_meta::get_plugin_meta; use log::{info, warn}; @@ -7,7 +5,6 @@ use reqwest::{Response, Url}; use serde::{Deserialize, Serialize}; use std::path::Path; use std::str::FromStr; -use log::info; use tauri::{AppHandle, Runtime, is_dev}; use ts_rs::TS; use yaak_common::api_client::yaak_api_client; From a1b1eafd39d714599b4b54eb0cea6f5dd75d7188 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 23 Jun 2025 09:46:54 -0700 Subject: [PATCH 278/996] Add links to plugins --- src-tauri/yaak-plugins/bindings/gen_search.ts | 2 +- src-tauri/yaak-plugins/src/api.rs | 3 ++- src-tauri/yaak-plugins/src/install.rs | 2 +- src-web/components/Settings/SettingsPlugins.tsx | 17 +++++++++++++++-- src-web/components/core/Link.tsx | 13 +++++++++---- src-web/hooks/useUninstallPlugin.tsx | 1 + 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src-tauri/yaak-plugins/bindings/gen_search.ts b/src-tauri/yaak-plugins/bindings/gen_search.ts index 9dbe01036..dd3c1ad72 100644 --- a/src-tauri/yaak-plugins/bindings/gen_search.ts +++ b/src-tauri/yaak-plugins/bindings/gen_search.ts @@ -2,4 +2,4 @@ export type PluginMetadata = { version: string, name: string, displayName: string, description: string | null, homepageUrl: string | null, repositoryUrl: string | null, }; -export type PluginVersion = { id: string, version: string, description: string | null, name: string, displayName: string, homepageUrl: string | null, repositoryUrl: string | null, checksum: string, readme: string | null, yanked: boolean, }; +export type PluginVersion = { id: string, version: string, url: string, description: string | null, name: string, displayName: string, homepageUrl: string | null, repositoryUrl: string | null, checksum: string, readme: string | null, yanked: boolean, }; diff --git a/src-tauri/yaak-plugins/src/api.rs b/src-tauri/yaak-plugins/src/api.rs index ba64d258b..b9d5a4fc3 100644 --- a/src-tauri/yaak-plugins/src/api.rs +++ b/src-tauri/yaak-plugins/src/api.rs @@ -1,3 +1,4 @@ +use crate::error::Error::ApiErr; use crate::error::Result; use crate::plugin_meta::get_plugin_meta; use log::{info, warn}; @@ -9,7 +10,6 @@ use tauri::{AppHandle, Runtime, is_dev}; use ts_rs::TS; use yaak_common::api_client::yaak_api_client; use yaak_models::query_manager::QueryManagerExt; -use crate::error::Error::ApiErr; pub async fn get_plugin( app_handle: &AppHandle, @@ -108,6 +108,7 @@ fn base_url(path: &str) -> Url { pub struct PluginVersion { pub id: String, pub version: String, + pub url: String, pub description: Option, pub name: String, pub display_name: String, diff --git a/src-tauri/yaak-plugins/src/install.rs b/src-tauri/yaak-plugins/src/install.rs index 105e9a085..9cc691f62 100644 --- a/src-tauri/yaak-plugins/src/install.rs +++ b/src-tauri/yaak-plugins/src/install.rs @@ -52,7 +52,7 @@ pub async fn download_and_install( checked_at: Some(Utc::now().naive_utc()), directory: plugin_dir_str.clone(), enabled: true, - url: None, + url: Some(plugin_version.url.clone()), ..Default::default() }, &UpdateSource::Background, diff --git a/src-web/components/Settings/SettingsPlugins.tsx b/src-web/components/Settings/SettingsPlugins.tsx index 37b0d4bef..ac19f90d7 100644 --- a/src-web/components/Settings/SettingsPlugins.tsx +++ b/src-web/components/Settings/SettingsPlugins.tsx @@ -18,6 +18,7 @@ import { useUninstallPlugin } from '../../hooks/useUninstallPlugin'; import { Button } from '../core/Button'; import { IconButton } from '../core/IconButton'; import { InlineCode } from '../core/InlineCode'; +import { Link } from '../core/Link'; import { LoadingIcon } from '../core/LoadingIcon'; import { PlainInput } from '../core/PlainInput'; import { HStack } from '../core/Stacks'; @@ -115,7 +116,15 @@ function PluginTableRow({ return ( - {pluginInfo.data.displayName} + + {plugin.url ? ( + + {pluginInfo.data.displayName} + + ) : ( + pluginInfo.data.displayName + )} + {pluginInfo.data?.version} @@ -187,7 +196,11 @@ function PluginSearch() { {results.data.plugins.map((plugin) => ( - {plugin.displayName} + + + {plugin.displayName} + + {plugin.version} diff --git a/src-web/components/core/Link.tsx b/src-web/components/core/Link.tsx index 7dbd3d1ed..82b8774f0 100644 --- a/src-web/components/core/Link.tsx +++ b/src-web/components/core/Link.tsx @@ -6,12 +6,13 @@ import { Icon } from './Icon'; interface Props extends HTMLAttributes { href: string; + noUnderline?: boolean; } -export function Link({ href, children, className, ...other }: Props) { +export function Link({ href, children, noUnderline, className, ...other }: Props) { const isExternal = href.match(/^https?:\/\//); - className = classNames(className, 'relative underline hover:text-violet-600'); + className = classNames(className, 'relative'); if (isExternal) { let finalHref = href; @@ -25,13 +26,17 @@ export function Link({ href, children, className, ...other }: Props) { href={finalHref} target="_blank" rel="noopener noreferrer" - className={classNames(className, 'pr-4 inline-flex items-center')} + className={classNames( + className, + 'pr-4 inline-flex items-center hover:underline', + !noUnderline && 'underline', + )} onClick={(e) => { e.preventDefault(); }} {...other} > - {children} + {children}
); diff --git a/src-web/hooks/useUninstallPlugin.tsx b/src-web/hooks/useUninstallPlugin.tsx index ebbbc9aae..038c541ef 100644 --- a/src-web/hooks/useUninstallPlugin.tsx +++ b/src-web/hooks/useUninstallPlugin.tsx @@ -11,6 +11,7 @@ export function useUninstallPlugin() { const confirmed = await showConfirmDelete({ id: 'uninstall-plugin-' + name, title: 'Uninstall Plugin', + confirmText: 'Uninstall', description: ( <> Permanently uninstall {name}? From 7be276752791d3a0da45bdbfa415c596ce0de76b Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 23 Jun 2025 09:51:44 -0700 Subject: [PATCH 279/996] Fix lint error --- src-web/components/GraphQLDocsExplorer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-web/components/GraphQLDocsExplorer.tsx b/src-web/components/GraphQLDocsExplorer.tsx index 7aeaa4d3e..4c3295349 100644 --- a/src-web/components/GraphQLDocsExplorer.tsx +++ b/src-web/components/GraphQLDocsExplorer.tsx @@ -494,7 +494,7 @@ function DocsExplorer({ return null; } - const field = schemaPointer as GraphQLField; + const field = schemaPointer as unknown as GraphQLField; const returnType = extractActualType(field.type); return ( From 1438e8bacc67d0651aaa7cad0eec2af5259422bf Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 23 Jun 2025 14:09:09 -0700 Subject: [PATCH 280/996] Upgrade eslint and fix issues --- .eslintignore | 6 - .eslintrc.cjs | 49 - eslint.config.cjs | 88 ++ package-lock.json | 1291 ++++++++++------- package.json | 13 +- src-web/components/ExportDataDialog.tsx | 1 - src-web/components/GraphQLDocsExplorer.tsx | 1233 +++++++--------- .../components/Settings/SettingsPlugins.tsx | 15 +- src-web/components/core/Tabs/Tabs.tsx | 5 +- src-web/hooks/useSyncWorkspaceRequestTitle.ts | 1 - src-web/lib/formatters.ts | 3 +- 11 files changed, 1382 insertions(+), 1323 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.cjs create mode 100644 eslint.config.cjs diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 3c19639bf..000000000 --- a/.eslintignore +++ /dev/null @@ -1,6 +0,0 @@ -node_modules/ -dist/ -.eslintrc.cjs -.prettierrc.cjs -src-web/postcss.config.cjs -src-web/vite.config.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index d050f7a6e..000000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,49 +0,0 @@ -module.exports = { - extends: [ - 'eslint:recommended', - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', - 'plugin:import/recommended', - 'plugin:jsx-a11y/recommended', - 'plugin:@typescript-eslint/recommended', - 'eslint-config-prettier', - ], - plugins: ['react-refresh'], - parser: '@typescript-eslint/parser', - parserOptions: { - project: ['./tsconfig.json'], - }, - ignorePatterns: [ - 'scripts/**/*', - 'packages/plugin-runtime/**/*', - 'packages/plugin-runtime-types/**/*', - 'src-tauri/**/*', - 'src-web/tailwind.config.cjs', - 'src-web/vite.config.ts', - ], - settings: { - react: { - version: 'detect', - }, - 'import/resolver': { - node: { - paths: ['src-web'], - extensions: ['.ts', '.tsx'], - }, - }, - }, - rules: { - 'react-refresh/only-export-components': 'error', - 'jsx-a11y/no-autofocus': 'off', - 'react/react-in-jsx-scope': 'off', - 'import/no-unresolved': 'off', - '@typescript-eslint/consistent-type-imports': [ - 'error', - { - prefer: 'type-imports', - disallowTypeAnnotations: true, - fixStyle: 'separate-type-imports', - }, - ], - }, -}; diff --git a/eslint.config.cjs b/eslint.config.cjs new file mode 100644 index 000000000..50f0bba4d --- /dev/null +++ b/eslint.config.cjs @@ -0,0 +1,88 @@ +const { defineConfig, globalIgnores } = require('eslint/config'); + +const { fixupConfigRules } = require('@eslint/compat'); + +const reactRefresh = require('eslint-plugin-react-refresh'); +const tsParser = require('@typescript-eslint/parser'); +const js = require('@eslint/js'); + +const { FlatCompat } = require('@eslint/eslintrc'); + +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +module.exports = defineConfig([ + { + extends: fixupConfigRules( + compat.extends( + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + 'plugin:import/recommended', + 'plugin:jsx-a11y/recommended', + 'plugin:@typescript-eslint/recommended', + 'eslint-config-prettier', + ), + ), + + plugins: { + 'react-refresh': reactRefresh, + }, + + languageOptions: { + parser: tsParser, + + parserOptions: { + project: ['./tsconfig.json'], + }, + }, + + settings: { + react: { + version: 'detect', + }, + + 'import/resolver': { + node: { + paths: ['src-web'], + extensions: ['.ts', '.tsx'], + }, + }, + }, + + rules: { + 'react-refresh/only-export-components': 'error', + 'jsx-a11y/no-autofocus': 'off', + 'react/react-in-jsx-scope': 'off', + 'import/no-unresolved': 'off', + + '@typescript-eslint/consistent-type-imports': [ + 'error', + { + prefer: 'type-imports', + disallowTypeAnnotations: true, + fixStyle: 'separate-type-imports', + }, + ], + }, + }, + globalIgnores([ + 'scripts/**/*', + 'packages/plugin-runtime/**/*', + 'packages/plugin-runtime-types/**/*', + 'src-tauri/**/*', + 'src-web/tailwind.config.cjs', + 'src-web/vite.config.ts', + ]), + globalIgnores([ + '**/node_modules/', + '**/dist/', + '**/.eslintrc.cjs', + '**/.prettierrc.cjs', + 'src-web/postcss.config.cjs', + 'src-web/vite.config.ts', + ]), +]); diff --git a/package-lock.json b/package-lock.json index 89cac4b88..f9462e8a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,16 +51,19 @@ "jotai": "^2.12.2" }, "devDependencies": { + "@eslint/compat": "^1.3.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "^9.29.0", "@tauri-apps/cli": "2.4.1", "@typescript-eslint/eslint-plugin": "^8.27.0", "@typescript-eslint/parser": "^8.27.0", "@yaakapp/cli": "^0.1.5", - "eslint": "^8", - "eslint-config-prettier": "^8", - "eslint-plugin-import": "^2.31.0", + "eslint": "^9.29.0", + "eslint-config-prettier": "^10.1.5", + "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.2", - "eslint-plugin-react": "^7.37.2", - "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^5.2.0", "nodejs-file-downloader": "^4.13.0", "npm-run-all": "^4.1.5", "prettier": "^3.4.2", @@ -1159,26 +1162,106 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/compat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.3.0.tgz", + "integrity": "sha512-ZBygRBqpDYiIHsN+d1WyHn3TYgzgpzLEcgJUxTATyiInQbKZz6wZb6+ljwdg8xeeOe4v03z6Uh6lELiw0/mVhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.10.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.1.tgz", + "integrity": "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.3.tgz", + "integrity": "sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -1186,16 +1269,16 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -1217,13 +1300,53 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "version": "9.29.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz", + "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==", "dev": true, "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.2.tgz", + "integrity": "sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.0.tgz", + "integrity": "sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@exodus/schemasafe": { @@ -1245,44 +1368,42 @@ "integrity": "sha512-I7xWjLs2YSVMc5gGx1Z3ZG1lgFpITPndpi8Ku55GeEIKpACCPQNS/OTqQbxgTCfq0Ncvcc+CrFov96itVh6Qvw==", "license": "MIT" }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "Apache-2.0", "engines": { - "node": "*" + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/module-importer": { @@ -1299,13 +1420,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, - "license": "BSD-3-Clause" + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -3836,9 +3963,9 @@ "optional": true }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -4062,13 +4189,13 @@ } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -4078,18 +4205,20 @@ } }, "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -4153,18 +4282,19 @@ } }, "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -4174,16 +4304,16 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4193,16 +4323,16 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4229,20 +4359,19 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -4287,6 +4416,16 @@ "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", "license": "MIT" }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -4683,16 +4822,15 @@ } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -5471,15 +5609,15 @@ "license": "BSD-2-Clause" }, "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5489,31 +5627,31 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -5945,19 +6083,6 @@ "redux": "^4.2.0" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -6109,58 +6234,66 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", + "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" @@ -6208,26 +6341,28 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", - "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", + "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", + "get-intrinsic": "^1.2.6", "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.3", - "safe-array-concat": "^1.1.2" + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" }, "engines": { "node": ">= 0.4" @@ -6246,40 +6381,44 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -6377,71 +6516,78 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "9.29.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz", + "integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.20.1", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.14.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.29.0", + "@eslint/plugin-kit": "^0.3.1", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.5.tgz", + "integrity": "sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==", "dev": true, "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, "peerDependencies": { "eslint": ">=7.0.0" } @@ -6469,9 +6615,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", - "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, "license": "MIT", "dependencies": { @@ -6497,30 +6643,30 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", - "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", "dependencies": { "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", + "eslint-module-utils": "^2.12.1", "hasown": "^2.0.2", - "is-core-module": "^2.15.1", + "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", + "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "engines": { @@ -6642,29 +6788,29 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.37.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", - "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", "dev": true, "license": "MIT", "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.2", + "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.1.0", + "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.8", + "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11", + "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "engines": { @@ -6675,9 +6821,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", - "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", "dev": true, "license": "MIT", "engines": { @@ -6763,9 +6909,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -6773,7 +6919,7 @@ "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -6803,6 +6949,19 @@ "concat-map": "0.0.1" } }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6817,18 +6976,31 @@ } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -7222,16 +7394,16 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/file-type": { @@ -7274,24 +7446,23 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, "license": "ISC" }, @@ -7341,12 +7512,18 @@ } }, "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/for-in": { @@ -7570,16 +7747,18 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -7696,15 +7875,15 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -8075,16 +8254,13 @@ } }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8231,11 +8407,14 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -8721,13 +8900,14 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -8744,13 +8924,17 @@ "license": "MIT" }, "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -8760,12 +8944,15 @@ } }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8784,13 +8971,13 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8819,9 +9006,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -8847,12 +9034,14 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -8863,12 +9052,13 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8924,13 +9114,16 @@ } }, "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8946,13 +9139,16 @@ } }, "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -9042,12 +9238,13 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -9056,16 +9253,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -9092,13 +9279,15 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -9133,12 +9322,12 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -9158,12 +9347,13 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -9173,12 +9363,14 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -9188,13 +9380,13 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -9216,13 +9408,16 @@ } }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9277,17 +9472,18 @@ } }, "node_modules/iterator.prototype": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", - "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", "dev": true, "license": "MIT", "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -11966,14 +12162,16 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -11984,15 +12182,16 @@ } }, "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-object-atoms": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -12046,13 +12245,14 @@ } }, "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -12183,6 +12383,24 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-event": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", @@ -13362,19 +13580,20 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -13413,14 +13632,16 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "set-function-name": "^2.0.2" }, "engines": { @@ -13700,15 +13921,16 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -13738,6 +13960,23 @@ ], "license": "MIT" }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", @@ -13749,15 +13988,14 @@ } }, "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -13876,6 +14114,21 @@ "node": ">=6.9" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -14679,24 +14932,25 @@ } }, "node_modules/string.prototype.matchall": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "regexp.prototype.flags": "^1.5.2", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -14736,16 +14990,19 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -14755,16 +15012,20 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -15281,13 +15542,6 @@ "array-includes": "^3.0.3" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -16021,46 +16275,33 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -16070,18 +16311,19 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -16091,18 +16333,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -16126,16 +16368,19 @@ } }, "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -16802,40 +17047,44 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-builtin-type": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", - "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", - "is-date-object": "^1.0.5", - "is-finalizationregistry": "^1.0.2", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", - "is-regex": "^1.1.4", + "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", - "which-boxed-primitive": "^1.0.2", + "which-boxed-primitive": "^1.1.0", "which-collection": "^1.0.2", - "which-typed-array": "^1.1.15" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -16869,15 +17118,17 @@ "license": "ISC" }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { diff --git a/package.json b/package.json index 41078f365..be616d6f1 100644 --- a/package.json +++ b/package.json @@ -67,16 +67,19 @@ "jotai": "^2.12.2" }, "devDependencies": { + "@eslint/compat": "^1.3.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "^9.29.0", "@tauri-apps/cli": "2.4.1", "@typescript-eslint/eslint-plugin": "^8.27.0", "@typescript-eslint/parser": "^8.27.0", "@yaakapp/cli": "^0.1.5", - "eslint": "^8", - "eslint-config-prettier": "^8", - "eslint-plugin-import": "^2.31.0", + "eslint": "^9.29.0", + "eslint-config-prettier": "^10.1.5", + "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.2", - "eslint-plugin-react": "^7.37.2", - "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^5.2.0", "nodejs-file-downloader": "^4.13.0", "npm-run-all": "^4.1.5", "prettier": "^3.4.2", diff --git a/src-web/components/ExportDataDialog.tsx b/src-web/components/ExportDataDialog.tsx index 35d8dd2b7..4474d58fa 100644 --- a/src-web/components/ExportDataDialog.tsx +++ b/src-web/components/ExportDataDialog.tsx @@ -113,7 +113,6 @@ function ExportDataDialogContent({ } /> - {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions,jsx-a11y/click-events-have-key-events */} setSelectedWorkspaces((prev) => ({ ...prev, [w.id]: !prev[w.id] }))} diff --git a/src-web/components/GraphQLDocsExplorer.tsx b/src-web/components/GraphQLDocsExplorer.tsx index 4c3295349..3940f59b9 100644 --- a/src-web/components/GraphQLDocsExplorer.tsx +++ b/src-web/components/GraphQLDocsExplorer.tsx @@ -1,114 +1,97 @@ -import { - useAtomValue -} from 'jotai'; -import { graphqlSchemaAtom } from "../atoms/graphqlSchemaAtom"; -import { Input } from "./core/Input"; +import { useAtomValue } from 'jotai'; +import { graphqlSchemaAtom } from '../atoms/graphqlSchemaAtom'; +import { Input } from './core/Input'; import type { - GraphQLSchema, - GraphQLOutputType, - GraphQLScalarType, - GraphQLField, - GraphQLList, - GraphQLInputType, - GraphQLNonNull, - GraphQLObjectType -} from "graphql"; -import { isNonNullType, isListType } from "graphql"; -import { Button } from "./core/Button"; + GraphQLSchema, + GraphQLOutputType, + GraphQLScalarType, + GraphQLField, + GraphQLList, + GraphQLInputType, + GraphQLNonNull, + GraphQLObjectType, +} from 'graphql'; +import { isNonNullType, isListType } from 'graphql'; +import { Button } from './core/Button'; import { useEffect, useState } from 'react'; -import { IconButton } from "./core/IconButton"; +import { IconButton } from './core/IconButton'; import { fuzzyFilter } from 'fuzzbunny'; function getRootTypes(graphqlSchema: GraphQLSchema) { - return ([ - graphqlSchema.getQueryType(), - graphqlSchema.getMutationType(), - graphqlSchema.getSubscriptionType(), - ] - .filter(Boolean) as NonNullable>[]) - .reduce( - ( - prev, - curr - ) => { - return { - ...prev, - [curr.name]: curr, - }; - }, - {} as Record>> - ) + return ( + [ + graphqlSchema.getQueryType(), + graphqlSchema.getMutationType(), + graphqlSchema.getSubscriptionType(), + ].filter(Boolean) as NonNullable>[] + ).reduce( + (prev, curr) => { + return { + ...prev, + [curr.name]: curr, + }; + }, + {} as Record>>, + ); } function getTypeIndices( - type: GraphQLAnyType, - context: IndexGenerationContext + type: GraphQLAnyType, + context: IndexGenerationContext, ): SearchIndexRecord[] { - const indices: SearchIndexRecord[] = []; - - if (!(type as GraphQLObjectType).name) { - return indices; - } - - indices.push({ - name: (type as GraphQLObjectType).name, - type: 'type', - schemaPointer: type, - args: '' - }); - - if ((type as GraphQLObjectType).getFields) { - indices.push( - ...getFieldsIndices((type as GraphQLObjectType).getFields(), context) - ) - } - - // remove duplicates from index - return indices.filter( - (x, i, array) => array.findIndex( - (y) => y.name === x.name && y.type === x.type - ) === i - ); + const indices: SearchIndexRecord[] = []; + + if (!(type as GraphQLObjectType).name) { + return indices; + } + + indices.push({ + name: (type as GraphQLObjectType).name, + type: 'type', + schemaPointer: type, + args: '', + }); + + if ((type as GraphQLObjectType).getFields) { + indices.push(...getFieldsIndices((type as GraphQLObjectType).getFields(), context)); + } + + // remove duplicates from index + return indices.filter( + (x, i, array) => array.findIndex((y) => y.name === x.name && y.type === x.type) === i, + ); } function getFieldsIndices( - fieldMap: FieldsMap, - context: IndexGenerationContext + fieldMap: FieldsMap, + context: IndexGenerationContext, ): SearchIndexRecord[] { - const indices: SearchIndexRecord[] = []; - - Object.values(fieldMap) - .forEach( - (field) => { - if (!field.name) { - return; - } - - const args = field.args && field.args.length > 0 - ? field.args.map((arg) => arg.name).join(', ') - : ''; - - indices.push({ - name: field.name, - type: context.rootType, - schemaPointer: field as unknown as Field, - args - }); - - if (field.type) { - indices.push( - ...getTypeIndices(field.type, context) - ) - } - } - ); - - // remove duplicates from index - return indices.filter( - (x, i, array) => array.findIndex( - (y) => y.name === x.name && y.type === x.type - ) === i - ); + const indices: SearchIndexRecord[] = []; + + Object.values(fieldMap).forEach((field) => { + if (!field.name) { + return; + } + + const args = + field.args && field.args.length > 0 ? field.args.map((arg) => arg.name).join(', ') : ''; + + indices.push({ + name: field.name, + type: context.rootType, + schemaPointer: field as unknown as Field, + args, + }); + + if (field.type) { + indices.push(...getTypeIndices(field.type, context)); + } + }); + + // remove duplicates from index + return indices.filter( + (x, i, array) => array.findIndex((y) => y.name === x.name && y.type === x.type) === i, + ); } type Field = NonNullable>; @@ -116,14 +99,14 @@ type FieldsMap = ReturnType; type GraphQLAnyType = FieldsMap[string]['type']; type SearchIndexRecord = { - name: string, - args: string, - type: 'field' | 'type' | 'Query' | 'Mutation' | 'Subscription', - schemaPointer: SchemaPointer + name: string; + args: string; + type: 'field' | 'type' | 'Query' | 'Mutation' | 'Subscription'; + schemaPointer: SchemaPointer; }; type IndexGenerationContext = { - rootType: 'Query' | 'Mutation' | 'Subscription'; + rootType: 'Query' | 'Mutation' | 'Subscription'; }; type SchemaPointer = Field | GraphQLOutputType | GraphQLInputType | null; @@ -131,636 +114,430 @@ type SchemaPointer = Field | GraphQLOutputType | GraphQLInputType | null; type ViewMode = 'explorer' | 'search' | 'field'; type HistoryRecord = { - schemaPointer: SchemaPointer, - viewMode: ViewMode + schemaPointer: SchemaPointer; + viewMode: ViewMode; }; -function DocsExplorer({ - graphqlSchema - }: { graphqlSchema: GraphQLSchema }) { - const [rootTypes, setRootTypes] = useState(getRootTypes(graphqlSchema)); - const [schemaPointer, setSchemaPointer] = useState(null); - const [history, setHistory] = useState([]); - const [searchIndex, setSearchIndex] = useState([]); - const [searchQuery, setSearchQuery] = useState(''); - const [searchResults, setSearchResults] = useState([]); - const [viewMode, setViewMode] = useState('explorer'); - - useEffect(() => { - setRootTypes(getRootTypes(graphqlSchema)); - }, [graphqlSchema]); - - useEffect(() => { - const typeMap = graphqlSchema.getTypeMap(); - - const index: SearchIndexRecord[] = Object.values(typeMap) - .filter( - (x) => !x.name.startsWith('__') - ) - .map( - (x) => ({ - name: x.name, - type: 'type', - schemaPointer: x, - args: '' - }) - ); - - Object.values(rootTypes) - .forEach( - (type) => { - index.push( - ...getFieldsIndices(type.getFields(), { rootType: type.name as any }) - ) - } - ) - - setSearchIndex( - index - .filter( - (x, i, array) => array.findIndex( - (y) => y.name === x.name && y.type === x.type - ) === i - ) - ); - }, [graphqlSchema, rootTypes]); - - useEffect( - () => { - if (!searchQuery) { - setSearchResults([]); - return; - } - - const results = fuzzyFilter( - searchIndex, - searchQuery, - { fields: ['name', 'args'] } - ) - .sort((a, b) => b.score - a.score) - .map((v) => v.item); - - setSearchResults(results); - }, - [searchIndex, searchQuery] - ); - - const goBack = () => { - if (history.length === 0) { - return; - } - - const newHistory = history.slice(0, history.length - 1); - - const prevHistoryRecord = newHistory[newHistory.length - 1]; - - if (prevHistoryRecord) { - const { schemaPointer: newPointer, viewMode } = prevHistoryRecord; - setHistory(newHistory); - setSchemaPointer(newPointer!); - setViewMode(viewMode); - - return; - } - - goHome(); - } - - const addToHistory = (historyRecord: HistoryRecord) => { - setHistory([...history, historyRecord]); - } - - const goHome = () => { - setHistory([]); - setSchemaPointer(null); - setViewMode('explorer'); - } - - const renderRootTypes = () => { - return ( -
- { - Object - .values(rootTypes) - .map( - (x) => ( - - ) - ) - } -
- ); - } - - const extractActualType = ( - type: GraphQLField['type'] | GraphQLInputType - ) => { - // check if non-null - if (isNonNullType(type) || isListType(type)) { - return extractActualType((type as GraphQLNonNull).ofType) - } - - return type; - } - - const onTypeClick = ( - type: GraphQLField['type'] | GraphQLInputType - ) => { - // check if non-null - if (isNonNullType(type)) { - onTypeClick((type as GraphQLNonNull).ofType) - - return; - } - - // check if list - if (isListType(type)) { - onTypeClick((type as GraphQLList).ofType); - - return; - } - - setSchemaPointer(type); - addToHistory({ - schemaPointer: type as Field, - viewMode: 'explorer', - }); - setViewMode('explorer'); - }; - - const onFieldClick = (field: GraphQLField) => { - setSchemaPointer(field as unknown as Field); - setViewMode('field'); - addToHistory({ - schemaPointer: field as unknown as Field, - viewMode: 'field', - }); - }; - - const renderSubFieldRecord = ( - field: FieldsMap[string], - options?: { - addable?: boolean, - } - ) => { - return ( -
- { - options?.addable - ? ( - - ) - : null - } -
-
- - { " " } - - - {/* Arguments block */ } - { - field.args && field.args.length > 0 - ? ( - <> - - { " " } - ( - { " " } - - { - field.args.map( - (arg, i, array) => ( - <> - - { " " } - - ) - ) - } - - ) - - - ) - : null - } - {/* End of Arguments Block */ } - { " " } - -
- { - field.description - ? ( -
- { field.description } -
- ) - : null - } -
-
- ); - }; - - const renderScalarField = () => { - const scalarField = schemaPointer as GraphQLScalarType; - - return ( -
- { scalarField.toConfig().description } -
- ); - }; - - const renderSubFields = () => { - if (!schemaPointer) { - return null; - } - - if ( - !(schemaPointer as Field).getFields - ) { - // Scalar field - return renderScalarField(); - } - - if (!(schemaPointer as Field).getFields()) { - return null; - } - - return Object.values((schemaPointer as Field).getFields()) - .map( - (x) => renderSubFieldRecord(x, { addable: true }) - ) - }; - - const renderFieldDocView = () => { - if (!schemaPointer) { - return null; - } - - return ( -
-
- { (schemaPointer as Field).name } -
- { - (schemaPointer as Field).getFields - ? ( -
- Fields -
- ) - : null - } -
- { renderSubFields() } -
-
- ) - } - - const renderExplorerView = () => { - if (history.length === 0) { - return renderRootTypes(); - } - - return renderFieldDocView() - }; - - const renderFieldView = () => { - if (!schemaPointer) { - return null; - } - - const field = schemaPointer as unknown as GraphQLField; - const returnType = extractActualType(field.type); - - return ( -
-
- { field.name } -
- {/* Arguments */} - { - field.args && field.args.length > 0 - ? ( -
-
- Arguments -
-
-
- { - field.args.map( - (arg, i, array) => ( - <> - - { " " } - - ) - ) - } -
-
-
- ) - : null - } - {/* End of Arguments */} - {/* Return type */} -
-
- Type -
-
- { returnType.name } -
-
- {/* End of Return type */} - {/* Fields */} - { - (returnType as GraphQLObjectType).getFields && Object.values((returnType as GraphQLObjectType).getFields()).length > 0 - ? ( -
-
- Fields -
-
- { - Object.values((returnType as GraphQLObjectType).getFields()) - .map( - (x) => renderSubFieldRecord(x) - ) - } -
-
- ) - : null - } - {/* End of Fields */} -
- ); - }; - - const renderTopBar = () => { - return ( -
- - -
- ); - }; - - const renderSearchView = () => { - return ( -
-
- Search results -
-
- { - searchResults - .map( - (result) => ( - - ) - ) - } -
-
- ); - }; - - const renderView = () => { - if (viewMode === 'field') { - return renderFieldView(); - } - - if (viewMode === 'search') { - return renderSearchView(); - } - - return renderExplorerView(); - }; - - return ( -
-
- { - history.length > 0 || viewMode === 'search' - ? renderTopBar() - : null - } -
- {/* Search bar */} -
- { - setSearchQuery(value); - } - } - onKeyDown={ - (e) => { - // check if enter - if (e.key === 'Enter' && viewMode !== 'search') { - addToHistory({ - schemaPointer: null, - viewMode: 'search', - }) - setViewMode('search'); - } - } - } - /> -
- {/* End of search bar */} -
- { renderView() } -
-
- ); +function DocsExplorer({ graphqlSchema }: { graphqlSchema: GraphQLSchema }) { + const [rootTypes, setRootTypes] = useState(getRootTypes(graphqlSchema)); + const [schemaPointer, setSchemaPointer] = useState(null); + const [history, setHistory] = useState([]); + const [searchIndex, setSearchIndex] = useState([]); + const [searchQuery, setSearchQuery] = useState(''); + const [searchResults, setSearchResults] = useState([]); + const [viewMode, setViewMode] = useState('explorer'); + + useEffect(() => { + setRootTypes(getRootTypes(graphqlSchema)); + }, [graphqlSchema]); + + useEffect(() => { + const typeMap = graphqlSchema.getTypeMap(); + + const index: SearchIndexRecord[] = Object.values(typeMap) + .filter((x) => !x.name.startsWith('__')) + .map((x) => ({ + name: x.name, + type: 'type', + schemaPointer: x, + args: '', + })); + + Object.values(rootTypes).forEach((type) => { + index.push( + ...getFieldsIndices(type.getFields(), { + rootType: type.name as IndexGenerationContext['rootType'], + }), + ); + }); + + setSearchIndex( + index.filter( + (x, i, array) => array.findIndex((y) => y.name === x.name && y.type === x.type) === i, + ), + ); + }, [graphqlSchema, rootTypes]); + + useEffect(() => { + if (!searchQuery) { + setSearchResults([]); + return; + } + + const results = fuzzyFilter(searchIndex, searchQuery, { fields: ['name', 'args'] }) + .sort((a, b) => b.score - a.score) + .map((v) => v.item); + + setSearchResults(results); + }, [searchIndex, searchQuery]); + + const goBack = () => { + if (history.length === 0) { + return; + } + + const newHistory = history.slice(0, history.length - 1); + + const prevHistoryRecord = newHistory[newHistory.length - 1]; + + if (prevHistoryRecord) { + const { schemaPointer: newPointer, viewMode } = prevHistoryRecord; + setHistory(newHistory); + setSchemaPointer(newPointer!); + setViewMode(viewMode); + + return; + } + + goHome(); + }; + + const addToHistory = (historyRecord: HistoryRecord) => { + setHistory([...history, historyRecord]); + }; + + const goHome = () => { + setHistory([]); + setSchemaPointer(null); + setViewMode('explorer'); + }; + + const renderRootTypes = () => { + return ( +
+ {Object.values(rootTypes).map((x) => ( + + ))} +
+ ); + }; + + const extractActualType = (type: GraphQLField['type'] | GraphQLInputType) => { + // check if non-null + if (isNonNullType(type) || isListType(type)) { + return extractActualType((type as GraphQLNonNull).ofType); + } + + return type; + }; + + const onTypeClick = (type: GraphQLField['type'] | GraphQLInputType) => { + // check if non-null + if (isNonNullType(type)) { + onTypeClick((type as GraphQLNonNull).ofType); + + return; + } + + // check if list + if (isListType(type)) { + onTypeClick((type as GraphQLList).ofType); + + return; + } + + setSchemaPointer(type); + addToHistory({ + schemaPointer: type as Field, + viewMode: 'explorer', + }); + setViewMode('explorer'); + }; + + const onFieldClick = (field: GraphQLField) => { + setSchemaPointer(field as unknown as Field); + setViewMode('field'); + addToHistory({ + schemaPointer: field as unknown as Field, + viewMode: 'field', + }); + }; + + const renderSubFieldRecord = ( + field: FieldsMap[string], + options?: { + addable?: boolean; + }, + ) => { + return ( +
+ {options?.addable ? ( + + ) : null} +
+
+ + + {/* Arguments block */} + {field.args && field.args.length > 0 ? ( + <> + ( + {field.args.map((arg, i, array) => ( + <> + + + + ))} + ) + + ) : null} + {/* End of Arguments Block */} + + +
+ {field.description ?
{field.description}
: null} +
+
+ ); + }; + + const renderScalarField = () => { + const scalarField = schemaPointer as GraphQLScalarType; + + return
{scalarField.toConfig().description}
; + }; + + const renderSubFields = () => { + if (!schemaPointer) { + return null; + } + + if (!(schemaPointer as Field).getFields) { + // Scalar field + return renderScalarField(); + } + + if (!(schemaPointer as Field).getFields()) { + return null; + } + + return Object.values((schemaPointer as Field).getFields()).map((x) => + renderSubFieldRecord(x, { addable: true }), + ); + }; + + const renderFieldDocView = () => { + if (!schemaPointer) { + return null; + } + + return ( +
+
{(schemaPointer as Field).name}
+ {(schemaPointer as Field).getFields ?
Fields
: null} +
{renderSubFields()}
+
+ ); + }; + + const renderExplorerView = () => { + if (history.length === 0) { + return renderRootTypes(); + } + + return renderFieldDocView(); + }; + + const renderFieldView = () => { + if (!schemaPointer) { + return null; + } + + const field = schemaPointer as unknown as GraphQLField; + const returnType = extractActualType(field.type); + + return ( +
+
{field.name}
+ {/* Arguments */} + {field.args && field.args.length > 0 ? ( +
+
Arguments
+
+
+ {field.args.map((arg, i, array) => ( + <> + + + + ))} +
+
+
+ ) : null} + {/* End of Arguments */} + {/* Return type */} +
+
Type
+
{returnType.name}
+
+ {/* End of Return type */} + {/* Fields */} + {(returnType as GraphQLObjectType).getFields && + Object.values((returnType as GraphQLObjectType).getFields()).length > 0 ? ( +
+
Fields
+
+ {Object.values((returnType as GraphQLObjectType).getFields()).map((x) => + renderSubFieldRecord(x), + )} +
+
+ ) : null} + {/* End of Fields */} +
+ ); + }; + + const renderTopBar = () => { + return ( +
+ + +
+ ); + }; + + const renderSearchView = () => { + return ( +
+
Search results
+
+ {searchResults.map((result) => ( + + ))} +
+
+ ); + }; + + const renderView = () => { + if (viewMode === 'field') { + return renderFieldView(); + } + + if (viewMode === 'search') { + return renderSearchView(); + } + + return renderExplorerView(); + }; + + return ( +
+
+ {history.length > 0 || viewMode === 'search' ? renderTopBar() : null} +
+ {/* Search bar */} +
+ { + setSearchQuery(value); + }} + onKeyDown={(e) => { + // check if enter + if (e.key === 'Enter' && viewMode !== 'search') { + addToHistory({ + schemaPointer: null, + viewMode: 'search', + }); + setViewMode('search'); + } + }} + /> +
+ {/* End of search bar */} +
{renderView()}
+
+ ); } export function GraphQLDocsExplorer() { - const graphqlSchema = useAtomValue(graphqlSchemaAtom); + const graphqlSchema = useAtomValue(graphqlSchemaAtom); - if (graphqlSchema) { - return ; - } + if (graphqlSchema) { + return ; + } - return
There is no schema
; + return
There is no schema
; } diff --git a/src-web/components/Settings/SettingsPlugins.tsx b/src-web/components/Settings/SettingsPlugins.tsx index ac19f90d7..b1001ddc7 100644 --- a/src-web/components/Settings/SettingsPlugins.tsx +++ b/src-web/components/Settings/SettingsPlugins.tsx @@ -1,13 +1,10 @@ import { useMutation, useQuery } from '@tanstack/react-query'; import { openUrl } from '@tauri-apps/plugin-opener'; -import { Plugin, pluginsAtom } from '@yaakapp-internal/models'; -import { - checkPluginUpdates, - installPlugin, - PluginVersion, - searchPlugins, -} from '@yaakapp-internal/plugins'; -import { PluginUpdatesResponse } from '@yaakapp-internal/plugins/bindings/gen_api'; +import type { Plugin } from '@yaakapp-internal/models'; +import { pluginsAtom } from '@yaakapp-internal/models'; +import type { PluginVersion } from '@yaakapp-internal/plugins'; +import { checkPluginUpdates, installPlugin, searchPlugins } from '@yaakapp-internal/plugins'; +import type { PluginUpdatesResponse } from '@yaakapp-internal/plugins/bindings/gen_api'; import { useAtomValue } from 'jotai'; import React, { useState } from 'react'; import { useDebouncedValue } from '../../hooks/useDebouncedValue'; @@ -190,7 +187,7 @@ function PluginSearch() { Name Version Description - + diff --git a/src-web/components/core/Tabs/Tabs.tsx b/src-web/components/core/Tabs/Tabs.tsx index 274dcd1ae..d476e1332 100644 --- a/src-web/components/core/Tabs/Tabs.tsx +++ b/src-web/components/core/Tabs/Tabs.tsx @@ -3,7 +3,8 @@ import type { ReactNode } from 'react'; import { memo, useEffect, useRef } from 'react'; import { ErrorBoundary } from '../../ErrorBoundary'; import { Icon } from '../Icon'; -import { RadioDropdown, RadioDropdownProps } from '../RadioDropdown'; +import type { RadioDropdownProps } from '../RadioDropdown'; +import { RadioDropdown } from '../RadioDropdown'; export type TabItem = | { @@ -49,7 +50,7 @@ export function Tabs({ const tabs = ref.current?.querySelectorAll(`[data-tab]`); for (const tab of tabs ?? []) { const v = tab.getAttribute('data-tab'); - let parent = tab.closest('.tabs-container'); + const parent = tab.closest('.tabs-container'); if (parent !== ref.current) { // Tab is part of a nested tab container, so ignore it } else if (v === value) { diff --git a/src-web/hooks/useSyncWorkspaceRequestTitle.ts b/src-web/hooks/useSyncWorkspaceRequestTitle.ts index 5a4a31131..d0e830bda 100644 --- a/src-web/hooks/useSyncWorkspaceRequestTitle.ts +++ b/src-web/hooks/useSyncWorkspaceRequestTitle.ts @@ -18,7 +18,6 @@ export function useSyncWorkspaceRequestTitle() { newTitle += ` [${activeEnvironment.name}]`; } if (activeRequest) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars newTitle += ` › ${resolvedModelName(activeRequest)}`; } diff --git a/src-web/lib/formatters.ts b/src-web/lib/formatters.ts index d6f74cfa6..214a53965 100644 --- a/src-web/lib/formatters.ts +++ b/src-web/lib/formatters.ts @@ -9,9 +9,8 @@ export async function tryFormatJson(text: string): Promise { try { const result = await invokeCmd('cmd_format_json', { text }); return result; - // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (err) { - console.warn("Failed to format JSON", err); + console.warn('Failed to format JSON', err); // Nothing } From f476d876133c38840a4c5243be2f35c3d1ea90f4 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 24 Jun 2025 06:21:07 -0700 Subject: [PATCH 281/996] Add back unsigned memory entitlement --- src-tauri/macos/entitlements.plist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src-tauri/macos/entitlements.plist b/src-tauri/macos/entitlements.plist index 7902d8a7e..bc9e10757 100644 --- a/src-tauri/macos/entitlements.plist +++ b/src-tauri/macos/entitlements.plist @@ -2,6 +2,10 @@ + + com.apple.security.cs.allow-unsigned-executable-memory + + From 8817be679bd101ce58a774438b2072407ab64de7 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 25 Jun 2025 07:10:11 -0700 Subject: [PATCH 282/996] Fix PKCE flow and clean up other flows --- .../src/bindings/gen_search.ts | 2 +- packages/plugin-runtime/src/index.ts | 4 + ...{getAccessToken.ts => fetchAccessToken.ts} | 6 +- .../src/getAccessTokenIfNotExpired.ts | 19 +++++ .../src/getOrRefreshAccessToken.ts | 53 +++++++------ .../src/grants/authorizationCode.ts | 77 +++++++++---------- .../src/grants/clientCredentials.ts | 13 ++-- plugins/auth-oauth2/src/grants/implicit.ts | 55 ++++++------- plugins/auth-oauth2/src/grants/password.ts | 9 ++- plugins/auth-oauth2/src/index.ts | 14 ++-- 10 files changed, 144 insertions(+), 108 deletions(-) rename plugins/auth-oauth2/src/{getAccessToken.ts => fetchAccessToken.ts} (92%) create mode 100644 plugins/auth-oauth2/src/getAccessTokenIfNotExpired.ts diff --git a/packages/plugin-runtime-types/src/bindings/gen_search.ts b/packages/plugin-runtime-types/src/bindings/gen_search.ts index 9dbe01036..dd3c1ad72 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_search.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_search.ts @@ -2,4 +2,4 @@ export type PluginMetadata = { version: string, name: string, displayName: string, description: string | null, homepageUrl: string | null, repositoryUrl: string | null, }; -export type PluginVersion = { id: string, version: string, description: string | null, name: string, displayName: string, homepageUrl: string | null, repositoryUrl: string | null, checksum: string, readme: string | null, yanked: boolean, }; +export type PluginVersion = { id: string, version: string, url: string, description: string | null, name: string, displayName: string, homepageUrl: string | null, repositoryUrl: string | null, checksum: string, readme: string | null, yanked: boolean, }; diff --git a/packages/plugin-runtime/src/index.ts b/packages/plugin-runtime/src/index.ts index afdd0e22f..b3e6c74b8 100644 --- a/packages/plugin-runtime/src/index.ts +++ b/packages/plugin-runtime/src/index.ts @@ -53,3 +53,7 @@ async function handleIncoming(msg: string) { plugin.sendToWorker(pluginEvent); } + +process.on('unhandledRejection', (reason, promise) => { + console.error('Unhandled Rejection at:', promise, 'reason:', reason); +}); diff --git a/plugins/auth-oauth2/src/getAccessToken.ts b/plugins/auth-oauth2/src/fetchAccessToken.ts similarity index 92% rename from plugins/auth-oauth2/src/getAccessToken.ts rename to plugins/auth-oauth2/src/fetchAccessToken.ts index 480a17b28..8e337a4ed 100644 --- a/plugins/auth-oauth2/src/getAccessToken.ts +++ b/plugins/auth-oauth2/src/fetchAccessToken.ts @@ -1,8 +1,8 @@ -import { Context, HttpRequest, HttpUrlParameter } from '@yaakapp/api'; +import type { Context, HttpRequest, HttpUrlParameter } from '@yaakapp/api'; import { readFileSync } from 'node:fs'; -import { AccessTokenRawResponse } from './store'; +import type { AccessTokenRawResponse } from './store'; -export async function getAccessToken( +export async function fetchAccessToken( ctx: Context, { accessTokenUrl, diff --git a/plugins/auth-oauth2/src/getAccessTokenIfNotExpired.ts b/plugins/auth-oauth2/src/getAccessTokenIfNotExpired.ts new file mode 100644 index 000000000..fed45b9e1 --- /dev/null +++ b/plugins/auth-oauth2/src/getAccessTokenIfNotExpired.ts @@ -0,0 +1,19 @@ +import type { Context } from '@yaakapp/api'; +import type { AccessToken } from './store'; +import { getToken } from './store'; + +export async function getAccessTokenIfNotExpired( + ctx: Context, + contextId: string, +): Promise { + const token = await getToken(ctx, contextId); + if (token == null || isTokenExpired(token)) { + return null; + } + + return token; +} + +export function isTokenExpired(token: AccessToken) { + return token.expiresAt && Date.now() > token.expiresAt; +} diff --git a/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts b/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts index 124009634..0b1b37e3d 100644 --- a/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts +++ b/plugins/auth-oauth2/src/getOrRefreshAccessToken.ts @@ -1,29 +1,34 @@ -import { Context, HttpRequest } from '@yaakapp/api'; +import type { Context, HttpRequest } from '@yaakapp/api'; import { readFileSync } from 'node:fs'; -import { AccessToken, AccessTokenRawResponse, deleteToken, getToken, storeToken } from './store'; - -export async function getOrRefreshAccessToken(ctx: Context, contextId: string, { - scope, - accessTokenUrl, - credentialsInBody, - clientId, - clientSecret, - forceRefresh, -}: { - scope: string | null; - accessTokenUrl: string; - credentialsInBody: boolean; - clientId: string; - clientSecret: string; - forceRefresh?: boolean; -}): Promise { +import { isTokenExpired } from './getAccessTokenIfNotExpired'; +import type { AccessToken, AccessTokenRawResponse } from './store'; +import { deleteToken, getToken, storeToken } from './store'; + +export async function getOrRefreshAccessToken( + ctx: Context, + contextId: string, + { + scope, + accessTokenUrl, + credentialsInBody, + clientId, + clientSecret, + forceRefresh, + }: { + scope: string | null; + accessTokenUrl: string; + credentialsInBody: boolean; + clientId: string; + clientSecret: string; + forceRefresh?: boolean; + }, +): Promise { const token = await getToken(ctx, contextId); if (token == null) { return null; } - const now = Date.now(); - const isExpired = token.expiresAt && now > token.expiresAt; + const isExpired = isTokenExpired(token); // Return the current access token if it's still valid if (!isExpired && !forceRefresh) { @@ -79,7 +84,9 @@ export async function getOrRefreshAccessToken(ctx: Context, contextId: string, { console.log('[oauth2] Got refresh token response', resp.status); if (resp.status < 200 || resp.status >= 300) { - throw new Error('Failed to refresh access token with status=' + resp.status + ' and body=' + body); + throw new Error( + 'Failed to refresh access token with status=' + resp.status + ' and body=' + body, + ); } let response; @@ -90,7 +97,9 @@ export async function getOrRefreshAccessToken(ctx: Context, contextId: string, { } if (response.error) { - throw new Error(`Failed to fetch access token with ${response.error} -> ${response.error_description}`); + throw new Error( + `Failed to fetch access token with ${response.error} -> ${response.error_description}`, + ); } const newResponse: AccessTokenRawResponse = { diff --git a/plugins/auth-oauth2/src/grants/authorizationCode.ts b/plugins/auth-oauth2/src/grants/authorizationCode.ts index b8da76189..abafcbe3d 100644 --- a/plugins/auth-oauth2/src/grants/authorizationCode.ts +++ b/plugins/auth-oauth2/src/grants/authorizationCode.ts @@ -1,8 +1,9 @@ -import { Context } from '@yaakapp/api'; +import type { Context } from '@yaakapp/api'; import { createHash, randomBytes } from 'node:crypto'; -import { getAccessToken } from '../getAccessToken'; +import { fetchAccessToken } from '../fetchAccessToken'; import { getOrRefreshAccessToken } from '../getOrRefreshAccessToken'; -import { AccessToken, getDataDirKey, storeToken } from '../store'; +import type { AccessToken } from '../store'; +import { getDataDirKey, storeToken } from '../store'; export const PKCE_SHA256 = 'S256'; export const PKCE_PLAIN = 'plain'; @@ -34,8 +35,8 @@ export async function getAuthorizationCode( audience: string | null; credentialsInBody: boolean; pkce: { - challengeMethod: string | null; - codeVerifier: string | null; + challengeMethod: string; + codeVerifier: string; } | null; tokenName: 'access_token' | 'id_token'; }, @@ -59,26 +60,25 @@ export async function getAuthorizationCode( if (state) authorizationUrl.searchParams.set('state', state); if (audience) authorizationUrl.searchParams.set('audience', audience); if (pkce) { - const verifier = pkce.codeVerifier || createPkceCodeVerifier(); - const challengeMethod = pkce.challengeMethod || DEFAULT_PKCE_METHOD; authorizationUrl.searchParams.set( 'code_challenge', - createPkceCodeChallenge(verifier, challengeMethod), + pkceCodeChallenge(pkce.codeVerifier, pkce.challengeMethod), ); - authorizationUrl.searchParams.set('code_challenge_method', challengeMethod); + authorizationUrl.searchParams.set('code_challenge_method', pkce.challengeMethod); } - return new Promise(async (resolve, reject) => { - const authorizationUrlStr = authorizationUrl.toString(); - const logsEnabled = (await ctx.store.get('enable_logs')) ?? false; - console.log('[oauth2] Authorizing', authorizationUrlStr); + const logsEnabled = (await ctx.store.get('enable_logs')) ?? false; + const dataDirKey = await getDataDirKey(ctx, contextId); + const authorizationUrlStr = authorizationUrl.toString(); + console.log('[oauth2] Authorizing', authorizationUrlStr); + // eslint-disable-next-line no-async-promise-executor + const code = await new Promise(async (resolve, reject) => { let foundCode = false; - - let { close } = await ctx.window.openUrl({ + const { close } = await ctx.window.openUrl({ url: authorizationUrlStr, label: 'oauth-authorization-url', - dataDirKey: await getDataDirKey(ctx, contextId), + dataDirKey, async onClose() { if (!foundCode) { reject(new Error('Authorization window closed')); @@ -89,6 +89,7 @@ export async function getAuthorizationCode( if (logsEnabled) console.log('[oauth2] Navigated to', urlStr); if (url.searchParams.has('error')) { + close(); return reject(new Error(`Failed to authorize: ${url.searchParams.get('error')}`)); } @@ -101,37 +102,35 @@ export async function getAuthorizationCode( // Close the window here, because we don't need it anymore! foundCode = true; close(); - - console.log('[oauth2] Code found'); - const response = await getAccessToken(ctx, { - grantType: 'authorization_code', - accessTokenUrl, - clientId, - clientSecret, - scope, - audience, - credentialsInBody, - params: [ - { name: 'code', value: code }, - ...(redirectUri ? [{ name: 'redirect_uri', value: redirectUri }] : []), - ], - }); - - try { - resolve(await storeToken(ctx, contextId, response, tokenName)); - } catch (err) { - reject(err); - } + resolve(code); }, }); }); + + console.log('[oauth2] Code found'); + const response = await fetchAccessToken(ctx, { + grantType: 'authorization_code', + accessTokenUrl, + clientId, + clientSecret, + scope, + audience, + credentialsInBody, + params: [ + { name: 'code', value: code }, + ...(pkce ? [{ name: 'code_verifier', value: pkce.codeVerifier }] : []), + ...(redirectUri ? [{ name: 'redirect_uri', value: redirectUri }] : []), + ], + }); + + return storeToken(ctx, contextId, response, tokenName); } -function createPkceCodeVerifier() { +export function genPkceCodeVerifier() { return encodeForPkce(randomBytes(32)); } -function createPkceCodeChallenge(verifier: string, method: string) { +function pkceCodeChallenge(verifier: string, method: string) { if (method === 'plain') { return verifier; } diff --git a/plugins/auth-oauth2/src/grants/clientCredentials.ts b/plugins/auth-oauth2/src/grants/clientCredentials.ts index 9543d9b7e..d565bd918 100644 --- a/plugins/auth-oauth2/src/grants/clientCredentials.ts +++ b/plugins/auth-oauth2/src/grants/clientCredentials.ts @@ -1,5 +1,6 @@ -import { Context } from '@yaakapp/api'; -import { getAccessToken } from '../getAccessToken'; +import type { Context } from '@yaakapp/api'; +import { fetchAccessToken } from '../fetchAccessToken'; +import { isTokenExpired } from '../getAccessTokenIfNotExpired'; import { getToken, storeToken } from '../store'; export async function getClientCredentials( @@ -22,13 +23,11 @@ export async function getClientCredentials( }, ) { const token = await getToken(ctx, contextId); - if (token) { - // resolve(token.response.access_token); - // TODO: Refresh token if expired - // return; + if (token && !isTokenExpired(token)) { + return token; } - const response = await getAccessToken(ctx, { + const response = await fetchAccessToken(ctx, { grantType: 'client_credentials', accessTokenUrl, audience, diff --git a/plugins/auth-oauth2/src/grants/implicit.ts b/plugins/auth-oauth2/src/grants/implicit.ts index 347fbfcdf..043d5379e 100644 --- a/plugins/auth-oauth2/src/grants/implicit.ts +++ b/plugins/auth-oauth2/src/grants/implicit.ts @@ -1,7 +1,9 @@ -import { Context } from '@yaakapp/api'; -import { AccessToken, AccessTokenRawResponse, getToken, storeToken } from '../store'; +import type { Context } from '@yaakapp/api'; +import { isTokenExpired } from '../getAccessTokenIfNotExpired'; +import type { AccessToken, AccessTokenRawResponse} from '../store'; +import { getToken, storeToken } from '../store'; -export function getImplicit( +export async function getImplicit( ctx: Context, contextId: string, { @@ -24,31 +26,30 @@ export function getImplicit( tokenName: 'access_token' | 'id_token'; }, ): Promise { - return new Promise(async (resolve, reject) => { - const token = await getToken(ctx, contextId); - if (token) { - // resolve(token.response.access_token); - // TODO: Refresh token if expired - // return; - } + const token = await getToken(ctx, contextId); + if (token != null && !isTokenExpired(token)) { + return token; + } - const authorizationUrl = new URL(`${authorizationUrlRaw ?? ''}`); - authorizationUrl.searchParams.set('response_type', 'token'); - authorizationUrl.searchParams.set('client_id', clientId); - if (redirectUri) authorizationUrl.searchParams.set('redirect_uri', redirectUri); - if (scope) authorizationUrl.searchParams.set('scope', scope); - if (state) authorizationUrl.searchParams.set('state', state); - if (audience) authorizationUrl.searchParams.set('audience', audience); - if (responseType.includes('id_token')) { - authorizationUrl.searchParams.set( - 'nonce', - String(Math.floor(Math.random() * 9999999999999) + 1), - ); - } + const authorizationUrl = new URL(`${authorizationUrlRaw ?? ''}`); + authorizationUrl.searchParams.set('response_type', 'token'); + authorizationUrl.searchParams.set('client_id', clientId); + if (redirectUri) authorizationUrl.searchParams.set('redirect_uri', redirectUri); + if (scope) authorizationUrl.searchParams.set('scope', scope); + if (state) authorizationUrl.searchParams.set('state', state); + if (audience) authorizationUrl.searchParams.set('audience', audience); + if (responseType.includes('id_token')) { + authorizationUrl.searchParams.set( + 'nonce', + String(Math.floor(Math.random() * 9999999999999) + 1), + ); + } - const authorizationUrlStr = authorizationUrl.toString(); + // eslint-disable-next-line no-async-promise-executor + const newToken = await new Promise(async (resolve, reject) => { let foundAccessToken = false; - let { close } = await ctx.window.openUrl({ + const authorizationUrlStr = authorizationUrl.toString(); + const { close } = await ctx.window.openUrl({ url: authorizationUrlStr, label: 'oauth-authorization-url', async onClose() { @@ -76,11 +77,13 @@ export function getImplicit( const response = Object.fromEntries(params) as unknown as AccessTokenRawResponse; try { - resolve(await storeToken(ctx, contextId, response)); + resolve(storeToken(ctx, contextId, response)); } catch (err) { reject(err); } }, }); }); + + return newToken; } diff --git a/plugins/auth-oauth2/src/grants/password.ts b/plugins/auth-oauth2/src/grants/password.ts index 2192345fd..f2a4d4013 100644 --- a/plugins/auth-oauth2/src/grants/password.ts +++ b/plugins/auth-oauth2/src/grants/password.ts @@ -1,7 +1,8 @@ -import { Context } from '@yaakapp/api'; -import { getAccessToken } from '../getAccessToken'; +import type { Context } from '@yaakapp/api'; +import { fetchAccessToken } from '../fetchAccessToken'; import { getOrRefreshAccessToken } from '../getOrRefreshAccessToken'; -import { AccessToken, storeToken } from '../store'; +import type { AccessToken} from '../store'; +import { storeToken } from '../store'; export async function getPassword( ctx: Context, @@ -37,7 +38,7 @@ export async function getPassword( return token; } - const response = await getAccessToken(ctx, { + const response = await fetchAccessToken(ctx, { accessTokenUrl, clientId, clientSecret, diff --git a/plugins/auth-oauth2/src/index.ts b/plugins/auth-oauth2/src/index.ts index 6ba526498..95bb71ef5 100644 --- a/plugins/auth-oauth2/src/index.ts +++ b/plugins/auth-oauth2/src/index.ts @@ -1,4 +1,4 @@ -import { +import type { Context, FormInputSelectOption, GetHttpAuthenticationConfigRequest, @@ -6,6 +6,7 @@ import { PluginDefinition, } from '@yaakapp/api'; import { + genPkceCodeVerifier, DEFAULT_PKCE_METHOD, getAuthorizationCode, PKCE_PLAIN, @@ -14,7 +15,8 @@ import { import { getClientCredentials } from './grants/clientCredentials'; import { getImplicit } from './grants/implicit'; import { getPassword } from './grants/password'; -import { AccessToken, deleteToken, getToken, resetDataDirKey } from './store'; +import type { AccessToken } from './store'; +import { deleteToken, getToken, resetDataDirKey } from './store'; type GrantType = 'authorization_code' | 'implicit' | 'password' | 'client_credentials'; @@ -219,9 +221,9 @@ export const plugin: PluginDefinition = { }, { type: 'text', - name: 'pkceCodeVerifier', + name: 'pkceCodeChallenge', label: 'Code Verifier', - placeholder: 'Automatically generated if not provided', + placeholder: 'Automatically generated when not set', optional: true, dynamic: hiddenIfNot(['authorization_code'], ({ usePkce }) => !!usePkce), }, @@ -325,8 +327,8 @@ export const plugin: PluginDefinition = { credentialsInBody, pkce: values.usePkce ? { - challengeMethod: stringArg(values, 'pkceChallengeMethod'), - codeVerifier: stringArgOrNull(values, 'pkceCodeVerifier'), + challengeMethod: stringArg(values, 'pkceChallengeMethod') || DEFAULT_PKCE_METHOD, + codeVerifier: stringArg(values, 'pkceCodeVerifier') || genPkceCodeVerifier(), } : null, tokenName: tokenName, From bb0cc16a70bd414b6a712ff6fb78f3245de6c51b Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 25 Jun 2025 08:17:17 -0700 Subject: [PATCH 283/996] Use API client for notifications/license --- src-tauri/src/error.rs | 13 ++++++++----- src-tauri/src/notifications.rs | 26 +++++++------------------ src-tauri/yaak-common/src/api_client.rs | 5 +++-- src-tauri/yaak-common/src/platform.rs | 13 +++++++++++++ src-tauri/yaak-license/src/error.rs | 3 +++ src-tauri/yaak-license/src/license.rs | 3 ++- src-web/components/Toasts.tsx | 2 +- src-web/hooks/useNotificationToast.tsx | 3 ++- 8 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src-tauri/src/error.rs b/src-tauri/src/error.rs index 4986e86c0..da590cb8d 100644 --- a/src-tauri/src/error.rs +++ b/src-tauri/src/error.rs @@ -12,7 +12,7 @@ pub enum Error { #[error(transparent)] SyncError(#[from] yaak_sync::error::Error), - + #[error(transparent)] CryptoError(#[from] yaak_crypto::error::Error), @@ -28,18 +28,21 @@ pub enum Error { #[error(transparent)] PluginError(#[from] yaak_plugins::error::Error), + #[error(transparent)] + CommonError(#[from] yaak_common::error::Error), + #[error("Updater error: {0}")] UpdaterError(#[from] tauri_plugin_updater::Error), - + #[error("JSON error: {0}")] JsonError(#[from] serde_json::error::Error), - + #[error("Tauri error: {0}")] TauriError(#[from] tauri::Error), - + #[error("Event source error: {0}")] EventSourceError(#[from] eventsource_client::Error), - + #[error("I/O error: {0}")] IOError(#[from] io::Error), diff --git a/src-tauri/src/notifications.rs b/src-tauri/src/notifications.rs index 88b28577e..d824e309d 100644 --- a/src-tauri/src/notifications.rs +++ b/src-tauri/src/notifications.rs @@ -2,12 +2,12 @@ use std::time::SystemTime; use crate::error::Result; use crate::history::get_num_launches; -use chrono::{DateTime, Duration, Utc}; +use chrono::{DateTime, Utc}; use log::debug; use reqwest::Method; use serde::{Deserialize, Serialize}; -use serde_json::Value; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow}; +use yaak_common::api_client::yaak_api_client; use yaak_common::platform::get_os; use yaak_license::{LicenseCheckStatus, check_license}; use yaak_models::query_manager::QueryManagerExt; @@ -28,6 +28,7 @@ pub struct YaakNotifier { #[serde(default, rename_all = "camelCase")] pub struct YaakNotification { timestamp: DateTime, + timeout: Option, id: String, message: String, action: Option, @@ -81,8 +82,8 @@ impl YaakNotifier { let settings = window.db().get_settings(); let num_launches = get_num_launches(app_handle).await; let info = app_handle.package_info().clone(); - let req = reqwest::Client::default() - .request(Method::GET, "https://notify.yaak.app/notifications") + let req = yaak_api_client(app_handle)? + .request(Method::GET, "http://localhost:9444/notifications") .query(&[ ("version", info.version.to_string().as_str()), ("launches", num_launches.to_string().as_str()), @@ -96,22 +97,9 @@ impl YaakNotifier { return Ok(()); } - let result = resp.json::().await?; - - // Support both single and multiple notifications. - // TODO: Remove support for single after April 2025 - let notifications = match result { - Value::Array(a) => a - .into_iter() - .map(|a| serde_json::from_value(a).unwrap()) - .collect::>(), - a @ _ => vec![serde_json::from_value(a).unwrap()], - }; - - for notification in notifications { - let age = notification.timestamp.signed_duration_since(Utc::now()); + for notification in resp.json::>().await? { let seen = get_kv(app_handle).await?; - if seen.contains(¬ification.id) || (age > Duration::days(2)) { + if seen.contains(¬ification.id) { debug!("Already seen notification {}", notification.id); continue; } diff --git a/src-tauri/yaak-common/src/api_client.rs b/src-tauri/yaak-common/src/api_client.rs index 79c40595c..f7ef75f16 100644 --- a/src-tauri/yaak-common/src/api_client.rs +++ b/src-tauri/yaak-common/src/api_client.rs @@ -1,5 +1,5 @@ use crate::error::Result; -use crate::platform::get_ua_platform; +use crate::platform::{get_ua_arch, get_ua_platform}; use reqwest::Client; use std::time::Duration; use tauri::http::{HeaderMap, HeaderValue}; @@ -8,7 +8,8 @@ use tauri::{AppHandle, Runtime}; pub fn yaak_api_client(app_handle: &AppHandle) -> Result { let platform = get_ua_platform(); let version = app_handle.package_info().version.clone(); - let ua = format!("Yaak/{version} ({platform})"); + let arch = get_ua_arch(); + let ua = format!("Yaak/{version} ({platform}; {arch})"); let mut default_headers = HeaderMap::new(); default_headers.insert("Accept", HeaderValue::from_str("application/json").unwrap()); diff --git a/src-tauri/yaak-common/src/platform.rs b/src-tauri/yaak-common/src/platform.rs index 4e1f2587c..0424e5bfb 100644 --- a/src-tauri/yaak-common/src/platform.rs +++ b/src-tauri/yaak-common/src/platform.rs @@ -21,3 +21,16 @@ pub fn get_ua_platform() -> &'static str { "Unknown" } } + +pub fn get_ua_arch() -> &'static str { + if cfg!(target_arch = "x86_64") { + "x86_64" + } else if cfg!(target_arch = "x86") { + "i386" + } else if cfg!(target_arch = "arm") { + "ARM" + } else if cfg!(target_arch = "aarch64") { + "ARM64" + } else { + "Unknown" + }} diff --git a/src-tauri/yaak-license/src/error.rs b/src-tauri/yaak-license/src/error.rs index 817926904..8db9f5ced 100644 --- a/src-tauri/yaak-license/src/error.rs +++ b/src-tauri/yaak-license/src/error.rs @@ -15,6 +15,9 @@ pub enum Error { #[error(transparent)] ModelError(#[from] yaak_models::error::Error), + #[error(transparent)] + CommonError(#[from] yaak_common::error::Error), + #[error("Internal server error")] ServerError, } diff --git a/src-tauri/yaak-license/src/license.rs b/src-tauri/yaak-license/src/license.rs index 48c40635b..dce35ebb5 100644 --- a/src-tauri/yaak-license/src/license.rs +++ b/src-tauri/yaak-license/src/license.rs @@ -7,6 +7,7 @@ use std::ops::Add; use std::time::Duration; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow, is_dev}; use ts_rs::TS; +use yaak_common::api_client::yaak_api_client; use yaak_common::platform::get_os; use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::UpdateSource; @@ -170,7 +171,7 @@ pub async fn check_license(window: &WebviewWindow) -> Result { info!("Checking license activation"); // A license has been activated, so let's check the license server - let client = reqwest::Client::new(); + let client = yaak_api_client(window.app_handle())?; let path = format!("/licenses/activations/{activation_id}/check"); let response = client.post(build_url(&path)).json(&payload).send().await?; diff --git a/src-web/components/Toasts.tsx b/src-web/components/Toasts.tsx index d4c9458f8..ec8f054a2 100644 --- a/src-web/components/Toasts.tsx +++ b/src-web/components/Toasts.tsx @@ -10,7 +10,7 @@ export type ToastInstance = { id: string; uniqueKey: string; message: ReactNode; - timeout: 3000 | 5000 | 8000 | null; + timeout: 3000 | 5000 | 8000 | (number & {}) | null; onClose?: ToastProps['onClose']; } & Omit; diff --git a/src-web/hooks/useNotificationToast.tsx b/src-web/hooks/useNotificationToast.tsx index d7a25a990..e56510877 100644 --- a/src-web/hooks/useNotificationToast.tsx +++ b/src-web/hooks/useNotificationToast.tsx @@ -13,6 +13,7 @@ export function useNotificationToast() { id: string; timestamp: string; message: string; + timeout?: number | null; action?: null | { url: string; label: string; @@ -23,7 +24,7 @@ export function useNotificationToast() { const actionLabel = payload.action?.label; showToast({ id: payload.id, - timeout: null, + timeout: payload.timeout ?? undefined, message: payload.message, onClose: () => { markRead(payload.id) From 25d50246c0c8975034de9b627461e3929d55ff66 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 27 Jun 2025 11:58:04 -0700 Subject: [PATCH 284/996] Revert notification endpoint URL for dev --- src-tauri/src/lib.rs | 2 +- src-tauri/src/notifications.rs | 4 ++-- src-tauri/yaak-models/src/queries/batch.rs | 2 +- src-tauri/yaak-plugins/src/api.rs | 10 +++++----- src-web/components/core/Editor/hyperlink/extension.ts | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 8ba4d5eaf..ed770eb63 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1302,7 +1302,7 @@ pub fn run() { tokio::time::sleep(Duration::from_millis(4000)).await; let val: State<'_, Mutex> = w.state(); let mut n = val.lock().await; - if let Err(e) = n.check(&w).await { + if let Err(e) = n.maybe_check(&w).await { warn!("Failed to check for notifications {}", e) } }); diff --git a/src-tauri/src/notifications.rs b/src-tauri/src/notifications.rs index d824e309d..d6e1d9b06 100644 --- a/src-tauri/src/notifications.rs +++ b/src-tauri/src/notifications.rs @@ -63,7 +63,7 @@ impl YaakNotifier { Ok(()) } - pub async fn check(&mut self, window: &WebviewWindow) -> Result<()> { + pub async fn maybe_check(&mut self, window: &WebviewWindow) -> Result<()> { let app_handle = window.app_handle(); let ignore_check = self.last_check.elapsed().unwrap().as_secs() < MAX_UPDATE_CHECK_SECONDS; @@ -83,7 +83,7 @@ impl YaakNotifier { let num_launches = get_num_launches(app_handle).await; let info = app_handle.package_info().clone(); let req = yaak_api_client(app_handle)? - .request(Method::GET, "http://localhost:9444/notifications") + .request(Method::GET, "https://notify.yaak.app/notifications") .query(&[ ("version", info.version.to_string().as_str()), ("launches", num_launches.to_string().as_str()), diff --git a/src-tauri/yaak-models/src/queries/batch.rs b/src-tauri/yaak-models/src/queries/batch.rs index 7be4a4984..9eeb1d3c1 100644 --- a/src-tauri/yaak-models/src/queries/batch.rs +++ b/src-tauri/yaak-models/src/queries/batch.rs @@ -22,7 +22,7 @@ impl<'a> DbContext<'a> { let x = self.upsert_workspace(&v, source)?; imported_resources.workspaces.push(x.clone()); } - info!("Upserted {} workspaces", imported_resources.environments.len()); + info!("Upserted {} workspaces", imported_resources.workspaces.len()); } if http_requests.len() > 0 { diff --git a/src-tauri/yaak-plugins/src/api.rs b/src-tauri/yaak-plugins/src/api.rs index b9d5a4fc3..297f2564b 100644 --- a/src-tauri/yaak-plugins/src/api.rs +++ b/src-tauri/yaak-plugins/src/api.rs @@ -17,7 +17,7 @@ pub async fn get_plugin( version: Option, ) -> Result { info!("Getting plugin: {name} {version:?}"); - let mut url = base_url(&format!("/{name}")); + let mut url = build_url(&format!("/{name}")); if let Some(version) = version { let mut query_pairs = url.query_pairs_mut(); query_pairs.append_pair("version", &version); @@ -36,7 +36,7 @@ pub async fn download_plugin_archive( let name = plugin_version.name.clone(); let version = plugin_version.version.clone(); info!("Downloading plugin: {name} {version}"); - let mut url = base_url(&format!("/{}/download", name)); + let mut url = build_url(&format!("/{}/download", name)); { let mut query_pairs = url.query_pairs_mut(); query_pairs.append_pair("version", &version); @@ -67,7 +67,7 @@ pub async fn check_plugin_updates( }) .collect(); - let url = base_url("/updates"); + let url = build_url("/updates"); let body = serde_json::to_vec(&PluginUpdatesResponse { plugins: name_versions, })?; @@ -84,7 +84,7 @@ pub async fn search_plugins( app_handle: &AppHandle, query: &str, ) -> Result { - let mut url = base_url("/search"); + let mut url = build_url("/search"); { let mut query_pairs = url.query_pairs_mut(); query_pairs.append_pair("query", query); @@ -93,7 +93,7 @@ pub async fn search_plugins( Ok(resp.json().await?) } -fn base_url(path: &str) -> Url { +fn build_url(path: &str) -> Url { let base_url = if is_dev() { "http://localhost:9444/api/v1/plugins" } else { diff --git a/src-web/components/core/Editor/hyperlink/extension.ts b/src-web/components/core/Editor/hyperlink/extension.ts index 0cd8b4986..98fe5803d 100644 --- a/src-web/components/core/Editor/hyperlink/extension.ts +++ b/src-web/components/core/Editor/hyperlink/extension.ts @@ -2,7 +2,7 @@ import type { DecorationSet, ViewUpdate } from '@codemirror/view'; import { Decoration, EditorView, hoverTooltip, MatchDecorator, ViewPlugin } from '@codemirror/view'; const REGEX = - /(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+*~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+*.~#?&/={}[\]]*))/g; + /(https?:\/\/([-a-zA-Z0-9@:%._+*~#=]{1,256})+(\.[a-zA-Z0-9()]{1,6})?\b([-a-zA-Z0-9()@:%_+*.~#?&/={}[\]]*))/g; const tooltip = hoverTooltip( (view, pos, side) => { From 9ab02130b0a1113ca76407c86099ecfed845bea3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 27 Jun 2025 13:32:52 -0700 Subject: [PATCH 285/996] Fix sync import issues: https://feedback.yaak.app/p/yaml-error-missing-field-type-at-line-4521-column-1 --- src-tauri/yaak-git/src/error.rs | 6 +++--- src-tauri/yaak-models/src/db_context.rs | 20 +++++++++++--------- src-tauri/yaak-models/src/lib.rs | 6 +++--- src-tauri/yaak-models/src/query_manager.rs | 3 +-- src-tauri/yaak-sync/src/error.rs | 7 +++++-- src-tauri/yaak-sync/src/models.rs | 17 +++++++++++++++-- 6 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src-tauri/yaak-git/src/error.rs b/src-tauri/yaak-git/src/error.rs index 9651601e6..b4207c224 100644 --- a/src-tauri/yaak-git/src/error.rs +++ b/src-tauri/yaak-git/src/error.rs @@ -15,7 +15,7 @@ pub enum Error { #[error("Yaml error: {0}")] YamlParseError(#[from] serde_yaml::Error), - #[error("Yaml error: {0}")] + #[error(transparent)] ModelError(#[from] yaak_models::error::Error), #[error("Sync error: {0}")] @@ -24,10 +24,10 @@ pub enum Error { #[error("I/o error: {0}")] IoError(#[from] io::Error), - #[error("Yaml error: {0}")] + #[error("JSON error: {0}")] JsonParseError(#[from] serde_json::Error), - #[error("Yaml error: {0}")] + #[error("UTF8 error: {0}")] Utf8ConversionError(#[from] FromUtf8Error), #[error("Git error: {0}")] diff --git a/src-tauri/yaak-models/src/db_context.rs b/src-tauri/yaak-models/src/db_context.rs index 04bb25527..4aee86d68 100644 --- a/src-tauri/yaak-models/src/db_context.rs +++ b/src-tauri/yaak-models/src/db_context.rs @@ -2,13 +2,14 @@ use crate::connection_or_tx::ConnectionOrTx; use crate::error::Error::DBRowNotFound; use crate::models::{AnyModel, UpsertModelInfo}; use crate::util::{ModelChangeEvent, ModelPayload, UpdateSource}; +use log::error; use rusqlite::OptionalExtension; use sea_query::{ Asterisk, Expr, IntoColumnRef, IntoIden, IntoTableRef, OnConflict, Query, SimpleExpr, SqliteQueryBuilder, }; use sea_query_rusqlite::RusqliteBinder; -use tokio::sync::mpsc; +use std::sync::mpsc; pub struct DbContext<'a> { pub(crate) events_tx: mpsc::Sender, @@ -150,16 +151,15 @@ impl<'a> DbContext<'a> { update_source: source.clone(), change: ModelChangeEvent::Upsert, }; - self.events_tx.try_send(payload).unwrap(); + + if let Err(e) = self.events_tx.send(payload.clone()) { + error!("Failed to send model change {source:?}: {e:?}"); + } Ok(m) } - pub(crate) fn delete<'s, M>( - &self, - m: &M, - update_source: &UpdateSource, - ) -> crate::error::Result + pub(crate) fn delete<'s, M>(&self, m: &M, source: &UpdateSource) -> crate::error::Result where M: Into + Clone + UpsertModelInfo, { @@ -171,11 +171,13 @@ impl<'a> DbContext<'a> { let payload = ModelPayload { model: m.clone().into(), - update_source: update_source.clone(), + update_source: source.clone(), change: ModelChangeEvent::Delete, }; - self.events_tx.try_send(payload).unwrap(); + if let Err(e) = self.events_tx.send(payload) { + error!("Failed to send model change {source:?}: {e:?}"); + } Ok(m.clone()) } } diff --git a/src-tauri/yaak-models/src/lib.rs b/src-tauri/yaak-models/src/lib.rs index 061aaa72b..6d8044a46 100644 --- a/src-tauri/yaak-models/src/lib.rs +++ b/src-tauri/yaak-models/src/lib.rs @@ -6,12 +6,12 @@ use log::error; use r2d2::Pool; use r2d2_sqlite::SqliteConnectionManager; use std::fs::create_dir_all; +use std::sync::mpsc; use std::time::Duration; use tauri::async_runtime::Mutex; use tauri::plugin::TauriPlugin; use tauri::{Emitter, Manager, Runtime, generate_handler}; use tauri_plugin_dialog::{DialogExt, MessageDialogKind}; -use tokio::sync::mpsc; mod commands; @@ -72,11 +72,11 @@ pub fn init() -> TauriPlugin { app_handle.manage(SqliteConnection::new(pool.clone())); { - let (tx, mut rx) = mpsc::channel(128); + let (tx, rx) = mpsc::channel(); app_handle.manage(QueryManager::new(pool, tx)); let app_handle = app_handle.clone(); tauri::async_runtime::spawn(async move { - while let Some(p) = rx.recv().await { + for p in rx { let name = match p.change { ModelChangeEvent::Upsert => "upserted_model", ModelChangeEvent::Delete => "deleted_model", diff --git a/src-tauri/yaak-models/src/query_manager.rs b/src-tauri/yaak-models/src/query_manager.rs index b1f696d47..10d639334 100644 --- a/src-tauri/yaak-models/src/query_manager.rs +++ b/src-tauri/yaak-models/src/query_manager.rs @@ -6,9 +6,8 @@ use crate::util::ModelPayload; use r2d2::Pool; use r2d2_sqlite::SqliteConnectionManager; use rusqlite::TransactionBehavior; -use std::sync::{Arc, Mutex}; +use std::sync::{mpsc, Arc, Mutex}; use tauri::{Manager, Runtime, State}; -use tokio::sync::mpsc; pub trait QueryManagerExt<'a, R> { fn db_manager(&'a self) -> State<'a, QueryManager>; diff --git a/src-tauri/yaak-sync/src/error.rs b/src-tauri/yaak-sync/src/error.rs index b82a9a80f..978a08da4 100644 --- a/src-tauri/yaak-sync/src/error.rs +++ b/src-tauri/yaak-sync/src/error.rs @@ -6,8 +6,11 @@ use thiserror::Error; pub enum Error { #[error("Yaml error: {0}")] YamlParseError(#[from] serde_yaml::Error), + + #[error("Sync parse error: {0}")] + ParseError(String), - #[error("Yaml error: {0}")] + #[error(transparent)] ModelError(#[from] yaak_models::error::Error), #[error("Unknown model: {0}")] @@ -16,7 +19,7 @@ pub enum Error { #[error("I/o error: {0}")] IoError(#[from] io::Error), - #[error("Yaml error: {0}")] + #[error("JSON error: {0}")] JsonParseError(#[from] serde_json::Error), #[error("Invalid sync file: {0}")] diff --git a/src-tauri/yaak-sync/src/models.rs b/src-tauri/yaak-sync/src/models.rs index a1dc3ffe6..e7e8e0742 100644 --- a/src-tauri/yaak-sync/src/models.rs +++ b/src-tauri/yaak-sync/src/models.rs @@ -1,6 +1,7 @@ use crate::error::Error::UnknownModel; use crate::error::Result; use chrono::NaiveDateTime; +use log::warn; use serde::{Deserialize, Serialize}; use sha1::{Digest, Sha1}; use std::fs; @@ -37,9 +38,21 @@ impl SyncModel { let ext = file_path.extension().unwrap_or_default(); if ext == "yml" || ext == "yaml" { - Ok(Some((serde_yaml::from_str(&content_str)?, checksum))) + Ok(match serde_yaml::from_str::(&content_str) { + Ok(m) => Some((m, checksum)), + Err(e) => { + warn!("Error parsing {:?} {:?}", file_path.file_name(), e); + None + } + }) } else if ext == "json" { - Ok(Some((serde_json::from_str(&content_str)?, checksum))) + Ok(match serde_json::from_str::(&content_str) { + Ok(m) => Some((m, checksum)), + Err(e) => { + warn!("Error parsing {:?} {:?}", file_path.file_name(), e); + None + } + }) } else { Ok(None) } From 81c3de807d84e7ba5c134213544439ea5689455f Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sat, 28 Jun 2025 07:29:24 -0700 Subject: [PATCH 286/996] Add json.minify --- plugins/template-function-json/src/index.ts | 41 +++++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/plugins/template-function-json/src/index.ts b/plugins/template-function-json/src/index.ts index 8383a0a12..5fb30e122 100755 --- a/plugins/template-function-json/src/index.ts +++ b/plugins/template-function-json/src/index.ts @@ -1,4 +1,4 @@ -import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; +import type { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api'; import { JSONPath } from 'jsonpath-plus'; export const plugin: PluginDefinition = { @@ -7,7 +7,13 @@ export const plugin: PluginDefinition = { name: 'json.jsonpath', description: 'Filter JSON-formatted text using JSONPath syntax', args: [ - { type: 'text', name: 'input', label: 'Input', multiLine: true, placeholder: '{ "foo": "bar" }' }, + { + type: 'text', + name: 'input', + label: 'Input', + multiLine: true, + placeholder: '{ "foo": "bar" }', + }, { type: 'text', name: 'query', label: 'Query', placeholder: '$..foo' }, { type: 'checkbox', name: 'formatted', label: 'Format Output' }, ], @@ -28,7 +34,7 @@ export const plugin: PluginDefinition = { } else { return JSON.stringify(filtered); } - } catch (e) { + } catch { return null; } }, @@ -37,12 +43,39 @@ export const plugin: PluginDefinition = { name: 'json.escape', description: 'Escape a JSON string, useful when using the output in JSON values', args: [ - { type: 'text', name: 'input', label: 'Input', multiLine: true, placeholder: 'Hello "World"' }, + { + type: 'text', + name: 'input', + label: 'Input', + multiLine: true, + placeholder: 'Hello "World"', + }, ], async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { const input = String(args.values.input ?? ''); return input.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); }, }, + { + name: 'json.minify', + description: 'Remove unnecessary whitespace from a valid JSON string.', + args: [ + { + type: 'editor', + language: 'json', + name: 'input', + label: 'Input', + placeholder: '{ "foo": "bar" }', + }, + ], + async onRender(_ctx: Context, args: CallTemplateFunctionArgs): Promise { + const input = String(args.values.input ?? ''); + try { + return JSON.stringify(JSON.parse(input)); + } catch { + return input; + } + }, + }, ], }; From 9b0a767ac8f36c7f00b9ef2801959ac8fd4e8203 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sat, 28 Jun 2025 07:37:15 -0700 Subject: [PATCH 287/996] Prevent command palette from jumping with less results --- src-web/components/core/Dialog.tsx | 2 +- src-web/hooks/useToggleCommandPalette.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src-web/components/core/Dialog.tsx b/src-web/components/core/Dialog.tsx index ae0df4f5b..715c7cb8d 100644 --- a/src-web/components/core/Dialog.tsx +++ b/src-web/components/core/Dialog.tsx @@ -47,7 +47,7 @@ export function Dialog({
Date: Sun, 29 Jun 2025 07:30:07 -0700 Subject: [PATCH 288/996] Hide large request bodies by default --- .../components/ConfirmLargeRequestBody.tsx | 76 ++++++++++ src-web/components/HttpRequestPane.tsx | 135 +++++++++--------- 2 files changed, 145 insertions(+), 66 deletions(-) create mode 100644 src-web/components/ConfirmLargeRequestBody.tsx diff --git a/src-web/components/ConfirmLargeRequestBody.tsx b/src-web/components/ConfirmLargeRequestBody.tsx new file mode 100644 index 000000000..3ec50da42 --- /dev/null +++ b/src-web/components/ConfirmLargeRequestBody.tsx @@ -0,0 +1,76 @@ +import type { HttpRequest } from '@yaakapp-internal/models'; +import { patchModel } from '@yaakapp-internal/models'; +import { type ReactNode } from 'react'; +import { useToggle } from '../hooks/useToggle'; +import { showConfirm } from '../lib/confirm'; +import { Banner } from './core/Banner'; +import { Button } from './core/Button'; +import { InlineCode } from './core/InlineCode'; +import { Link } from './core/Link'; +import { SizeTag } from './core/SizeTag'; +import { HStack } from './core/Stacks'; + +interface Props { + children: ReactNode; + request: HttpRequest; +} + +const LARGE_TEXT_BYTES = 2 * 1000 * 1000; + +export function ConfirmLargeRequestBody({ children, request }: Props) { + const [showLargeResponse, toggleShowLargeResponse] = useToggle(); + + if (request.body?.text == null) { + return children; + } + + const contentLength = request.body.text.length ?? 0; + const tooLargeBytes = LARGE_TEXT_BYTES; + const isLarge = contentLength > tooLargeBytes; + if (!showLargeResponse && isLarge) { + return ( + +

+ Rendering content over{' '} + + + {' '} + may impact performance. +

+

+ See{' '} + + Working With Large Values + {' '} + for tips. +

+ + + + +
+ ); + } + + return <>{children}; +} diff --git a/src-web/components/HttpRequestPane.tsx b/src-web/components/HttpRequestPane.tsx index eedab5da1..334382d8e 100644 --- a/src-web/components/HttpRequestPane.tsx +++ b/src-web/components/HttpRequestPane.tsx @@ -35,6 +35,7 @@ import { prepareImportQuerystring } from '../lib/prepareImportQuerystring'; import { resolvedModelName } from '../lib/resolvedModelName'; import { showToast } from '../lib/toast'; import { BinaryFileEditor } from './BinaryFileEditor'; +import { ConfirmLargeRequestBody } from './ConfirmLargeRequestBody'; import { CountBadge } from './core/CountBadge'; import { Editor } from './core/Editor/Editor'; import type { GenericCompletionConfig } from './core/Editor/genericCompletion'; @@ -373,72 +374,74 @@ export function HttpRequestPane({ style, fullHeight, className, activeRequest }: /> - {activeRequest.bodyType === BODY_TYPE_JSON ? ( - - ) : activeRequest.bodyType === BODY_TYPE_XML ? ( - - ) : activeRequest.bodyType === BODY_TYPE_GRAPHQL ? ( - - ) : activeRequest.bodyType === BODY_TYPE_FORM_URLENCODED ? ( - - ) : activeRequest.bodyType === BODY_TYPE_FORM_MULTIPART ? ( - - ) : activeRequest.bodyType === BODY_TYPE_BINARY ? ( - patchModel(activeRequest, { body })} - onChangeContentType={handleContentTypeChange} - /> - ) : typeof activeRequest.bodyType === 'string' ? ( - - ) : ( - No Body - )} + + {activeRequest.bodyType === BODY_TYPE_JSON ? ( + + ) : activeRequest.bodyType === BODY_TYPE_XML ? ( + + ) : activeRequest.bodyType === BODY_TYPE_GRAPHQL ? ( + + ) : activeRequest.bodyType === BODY_TYPE_FORM_URLENCODED ? ( + + ) : activeRequest.bodyType === BODY_TYPE_FORM_MULTIPART ? ( + + ) : activeRequest.bodyType === BODY_TYPE_BINARY ? ( + patchModel(activeRequest, { body })} + onChangeContentType={handleContentTypeChange} + /> + ) : typeof activeRequest.bodyType === 'string' ? ( + + ) : ( + No Body + )} +
From 99975c32233ac235209accb138da457ecfab714b Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 29 Jun 2025 08:02:55 -0700 Subject: [PATCH 289/996] Fix sidebar folder dragging collapse https://feedback.yaak.app/p/a-folder-may-hide-its-content-if-i-move-a --- src-tauri/yaak-git/src/git.rs | 2 +- src-web/components/sidebar/Sidebar.tsx | 4 ++-- src-web/components/sidebar/SidebarAtoms.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src-tauri/yaak-git/src/git.rs b/src-tauri/yaak-git/src/git.rs index 1ac366826..9f678484b 100644 --- a/src-tauri/yaak-git/src/git.rs +++ b/src-tauri/yaak-git/src/git.rs @@ -265,7 +265,7 @@ pub fn git_status(dir: &Path) -> Result { None => None, Some(t) => match t.get_path(&Path::new(&rela_path)) { Ok(entry) => { - let obj = entry.to_object(&repo).unwrap(); + let obj = entry.to_object(&repo)?; let content = obj.as_blob().unwrap().content(); let name = Path::new(entry.name().unwrap_or_default()); SyncModel::from_bytes(content.into(), name)?.map(|m| m.0) diff --git a/src-web/components/sidebar/Sidebar.tsx b/src-web/components/sidebar/Sidebar.tsx index b0821316f..f045f27e6 100644 --- a/src-web/components/sidebar/Sidebar.tsx +++ b/src-web/components/sidebar/Sidebar.tsx @@ -232,6 +232,7 @@ export function Sidebar({ className }: Props) { const handleEnd = useCallback( async (itemId) => { setHoveredTree(null); + setDraggingId(null); handleClearSelected(); if (hoveredTree == null || hoveredIndex == null) { @@ -278,9 +279,8 @@ export function Sidebar({ className }: Props) { ); } else { const sortPriority = afterPriority - (afterPriority - beforePriority) / 2; - return patchModelById(child.model, child.id, { sortPriority, folderId }); + await patchModelById(child.model, child.id, { sortPriority, folderId }); } - setDraggingId(null); }, [handleClearSelected, hoveredTree, hoveredIndex, treeParentMap], ); diff --git a/src-web/components/sidebar/SidebarAtoms.ts b/src-web/components/sidebar/SidebarAtoms.ts index f467f06eb..b5ea06fe5 100644 --- a/src-web/components/sidebar/SidebarAtoms.ts +++ b/src-web/components/sidebar/SidebarAtoms.ts @@ -6,7 +6,7 @@ import { type WebsocketRequest, } from '@yaakapp-internal/models'; -// This is an atom so we can use it in the child items to avoid re-rendering the entire list +// This is an atom, so we can use it in the child items to avoid re-rendering the entire list import { atom } from 'jotai'; import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace'; import { allRequestsAtom } from '../../hooks/useAllRequests'; From fa62f88fa4760abe5752b1ad97b7c6765c03acb2 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 29 Jun 2025 08:40:14 -0700 Subject: [PATCH 290/996] Allow moving requests and folders to end of list --- src-web/components/sidebar/Sidebar.tsx | 30 +++++++++++++++++++--- src-web/components/sidebar/SidebarItem.tsx | 14 +++------- src-web/components/sidebar/dnd.ts | 9 +++++++ 3 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 src-web/components/sidebar/dnd.ts diff --git a/src-web/components/sidebar/Sidebar.tsx b/src-web/components/sidebar/Sidebar.tsx index f045f27e6..a5038eda5 100644 --- a/src-web/components/sidebar/Sidebar.tsx +++ b/src-web/components/sidebar/Sidebar.tsx @@ -9,6 +9,7 @@ import { getAnyModel, patchModelById } from '@yaakapp-internal/models'; import classNames from 'classnames'; import { useAtom, useAtomValue } from 'jotai'; import React, { useCallback, useRef, useState } from 'react'; +import { useDrop } from 'react-dnd'; import { useKey, useKeyPressEvent } from 'react-use'; import { activeRequestIdAtom } from '../../hooks/useActiveRequestId'; import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace'; @@ -22,6 +23,8 @@ import { router } from '../../lib/router'; import { setWorkspaceSearchParams } from '../../lib/setWorkspaceSearchParams'; import { ContextMenu } from '../core/Dropdown'; import { GitDropdown } from '../GitDropdown'; +import type { DragItem } from './dnd'; +import { ItemTypes } from './dnd'; import { sidebarSelectedIdAtom, sidebarTreeAtom } from './SidebarAtoms'; import type { SidebarItemProps } from './SidebarItem'; import { SidebarItems } from './SidebarItems'; @@ -204,15 +207,22 @@ export function Sidebar({ className }: Props) { [hasFocus, selectableRequests, selectedId, setSelectedId, setSelectedTree], ); + const handleMoveToSidebarEnd = useCallback(() => { + setHoveredTree(tree); + // Put at the end of the top tree + setHoveredIndex(tree?.children?.length ?? 0); + }, [tree]); + const handleMove = useCallback( - async (id, side) => { + (id, side) => { let hoveredTree = treeParentMap[id] ?? null; const dragIndex = hoveredTree?.children.findIndex((n) => n.id === id) ?? -99; const hoveredItem = hoveredTree?.children[dragIndex] ?? null; let hoveredIndex = dragIndex + (side === 'above' ? 0 : 1); - const isHoveredItemCollapsed = - hoveredItem != null ? getSidebarCollapsedMap()[hoveredItem.id] : false; + const collapsedMap = getSidebarCollapsedMap(); + const isHoveredItemCollapsed = hoveredItem != null ? collapsedMap[hoveredItem.id] : false; + if (hoveredItem?.model === 'folder' && side === 'below' && !isHoveredItemCollapsed) { // Move into the folder if it's open and we're moving below it hoveredTree = hoveredTree?.children.find((n) => n.id === id) ?? null; @@ -298,6 +308,20 @@ export function Sidebar({ className }: Props) { const mainContextMenuItems = useCreateDropdownItems({ folderId: null }); + const [, connectDrop] = useDrop( + { + accept: ItemTypes.REQUEST, + hover: (_, monitor) => { + if (sidebarRef.current == null) return; + if (!monitor.isOver({ shallow: true })) return; + handleMoveToSidebarEnd(); + }, + }, + [handleMoveToSidebarEnd], + ); + + connectDrop(sidebarRef); + // Not ready to render yet if (tree == null) { return null; diff --git a/src-web/components/sidebar/SidebarItem.tsx b/src-web/components/sidebar/SidebarItem.tsx index 8a31de376..799411194 100644 --- a/src-web/components/sidebar/SidebarItem.tsx +++ b/src-web/components/sidebar/SidebarItem.tsx @@ -20,15 +20,13 @@ import { HttpMethodTag } from '../core/HttpMethodTag'; import { HttpStatusTag } from '../core/HttpStatusTag'; import { Icon } from '../core/Icon'; import { LoadingIcon } from '../core/LoadingIcon'; +import type { DragItem} from './dnd'; +import { ItemTypes } from './dnd'; import type { SidebarTreeNode } from './Sidebar'; import { sidebarSelectedIdAtom } from './SidebarAtoms'; import { SidebarItemContextMenu } from './SidebarItemContextMenu'; import type { SidebarItemsProps } from './SidebarItems'; -enum ItemTypes { - REQUEST = 'request', -} - export type SidebarItemProps = { className?: string; itemId: string; @@ -44,11 +42,6 @@ export type SidebarItemProps = { latestWebsocketConnection: WebsocketConnection | null; } & Pick; -type DragItem = { - id: string; - itemName: string; -}; - export const SidebarItem = memo(function SidebarItem({ itemName, itemId, @@ -69,9 +62,10 @@ export const SidebarItem = memo(function SidebarItem({ const [, connectDrop] = useDrop( { - accept: ItemTypes.REQUEST, + accept: [ItemTypes.REQUEST, ItemTypes.SIDEBAR], hover: (_, monitor) => { if (!ref.current) return; + if (!monitor.isOver()) return; const hoverBoundingRect = ref.current?.getBoundingClientRect(); const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; const clientOffset = monitor.getClientOffset(); diff --git a/src-web/components/sidebar/dnd.ts b/src-web/components/sidebar/dnd.ts new file mode 100644 index 000000000..1d3023298 --- /dev/null +++ b/src-web/components/sidebar/dnd.ts @@ -0,0 +1,9 @@ +export enum ItemTypes { + REQUEST = 'request', + SIDEBAR = 'sidebar', +} + +export type DragItem = { + id: string; + itemName: string; +}; From ff26cc1344f12a92bb65f41483d06865ff1d4bb9 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 2 Jul 2025 07:47:36 -0700 Subject: [PATCH 291/996] Tweaks --- packages/plugin-runtime-types/README.md | 2 +- packages/plugin-runtime-types/package.json | 2 +- src-tauri/yaak-models/src/db_context.rs | 12 +++++++----- src-tauri/yaak-models/src/error.rs | 5 +---- src-tauri/yaak-models/src/queries/http_requests.rs | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/plugin-runtime-types/README.md b/packages/plugin-runtime-types/README.md index cce0d5fb9..a7ac97e17 100644 --- a/packages/plugin-runtime-types/README.md +++ b/packages/plugin-runtime-types/README.md @@ -24,5 +24,5 @@ the [Quick Start Guide](https://feedback.yaak.app/help/articles/6911763-plugins- If you prefer starting from scratch, manually install the types package: ```shell -npm install @yaakapp/api +npm install -D @yaakapp/api ``` diff --git a/packages/plugin-runtime-types/package.json b/packages/plugin-runtime-types/package.json index cd7decf20..24181d78a 100644 --- a/packages/plugin-runtime-types/package.json +++ b/packages/plugin-runtime-types/package.json @@ -1,6 +1,6 @@ { "name": "@yaakapp/api", - "version": "0.6.4", + "version": "0.6.5", "keywords": [ "api-client", "insomnia-alternative", diff --git a/src-tauri/yaak-models/src/db_context.rs b/src-tauri/yaak-models/src/db_context.rs index 4aee86d68..9df28f566 100644 --- a/src-tauri/yaak-models/src/db_context.rs +++ b/src-tauri/yaak-models/src/db_context.rs @@ -1,5 +1,4 @@ use crate::connection_or_tx::ConnectionOrTx; -use crate::error::Error::DBRowNotFound; use crate::models::{AnyModel, UpsertModelInfo}; use crate::util::{ModelChangeEvent, ModelPayload, UpdateSource}; use log::error; @@ -25,10 +24,13 @@ impl<'a> DbContext<'a> { where M: Into + Clone + UpsertModelInfo, { - match self.find_optional::(col, value) { - Some(v) => Ok(v), - None => Err(DBRowNotFound(format!("{:?}", M::table_name()))), - } + let (sql, params) = Query::select() + .from(M::table_name()) + .column(Asterisk) + .cond_where(Expr::col(col).eq(value)) + .build_rusqlite(SqliteQueryBuilder); + let mut stmt = self.conn.prepare(sql.as_str()).expect("Failed to prepare query"); + Ok(stmt.query_row(&*params.as_params(), M::from_row)?) } pub(crate) fn find_optional<'s, M>( diff --git a/src-tauri/yaak-models/src/error.rs b/src-tauri/yaak-models/src/error.rs index d64ff9d20..466e75b6c 100644 --- a/src-tauri/yaak-models/src/error.rs +++ b/src-tauri/yaak-models/src/error.rs @@ -20,7 +20,7 @@ pub enum Error { #[error("Model error: {0}")] GenericError(String), - + #[error("DB Migration Failed: {0}")] MigrationError(String), @@ -30,9 +30,6 @@ pub enum Error { #[error("Multiple base environments for {0}. Delete duplicates before continuing.")] MultipleBaseEnvironments(String), - #[error("Database row not found: {0}")] - DBRowNotFound(String), - #[error("unknown error")] Unknown, } diff --git a/src-tauri/yaak-models/src/queries/http_requests.rs b/src-tauri/yaak-models/src/queries/http_requests.rs index 021f9695b..0eff6bc43 100644 --- a/src-tauri/yaak-models/src/queries/http_requests.rs +++ b/src-tauri/yaak-models/src/queries/http_requests.rs @@ -64,7 +64,7 @@ impl<'a> DbContext<'a> { return self.resolve_auth_for_folder(&folder); } - let workspace = self.get_workspace(&http_request.workspace_id)?; + let workspace = self.get_workspace("invalid")?; Ok(self.resolve_auth_for_workspace(&workspace)) } From a6979cf37e4b10bbebd3731419f6c9f0289438e9 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 2 Jul 2025 08:14:52 -0700 Subject: [PATCH 292/996] Print table/col/val when row not found --- src-tauri/yaak-models/src/db_context.rs | 27 ++++++++++--- src-tauri/yaak-models/src/models.rs | 38 +++++++++---------- .../yaak-models/src/queries/http_requests.rs | 2 +- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src-tauri/yaak-models/src/db_context.rs b/src-tauri/yaak-models/src/db_context.rs index 9df28f566..06e0485e0 100644 --- a/src-tauri/yaak-models/src/db_context.rs +++ b/src-tauri/yaak-models/src/db_context.rs @@ -1,4 +1,6 @@ use crate::connection_or_tx::ConnectionOrTx; +use crate::error::Error::ModelNotFound; +use crate::error::Result; use crate::models::{AnyModel, UpsertModelInfo}; use crate::util::{ModelChangeEvent, ModelPayload, UpdateSource}; use log::error; @@ -8,6 +10,7 @@ use sea_query::{ SqliteQueryBuilder, }; use sea_query_rusqlite::RusqliteBinder; +use std::fmt::Debug; use std::sync::mpsc; pub struct DbContext<'a> { @@ -18,19 +21,33 @@ pub struct DbContext<'a> { impl<'a> DbContext<'a> { pub(crate) fn find_one<'s, M>( &self, - col: impl IntoColumnRef, - value: impl Into, - ) -> crate::error::Result + col: impl IntoColumnRef + IntoIden + Clone, + value: impl Into + Debug, + ) -> Result where M: Into + Clone + UpsertModelInfo, { + let value_debug = format!("{:?}", value); + + let value_expr = value.into(); let (sql, params) = Query::select() .from(M::table_name()) .column(Asterisk) - .cond_where(Expr::col(col).eq(value)) + .cond_where(Expr::col(col.clone()).eq(value_expr)) .build_rusqlite(SqliteQueryBuilder); let mut stmt = self.conn.prepare(sql.as_str()).expect("Failed to prepare query"); - Ok(stmt.query_row(&*params.as_params(), M::from_row)?) + match stmt.query_row(&*params.as_params(), M::from_row) { + Ok(result) => Ok(result), + Err(rusqlite::Error::QueryReturnedNoRows) => { + Err(ModelNotFound(format!( + r#"table "{}" {} == {}"#, + M::table_name().into_iden().to_string(), + col.into_iden().to_string(), + value_debug + ))) + } + Err(e) => Err(crate::error::Error::SqlError(e)), + } } pub(crate) fn find_optional<'s, M>( diff --git a/src-tauri/yaak-models/src/models.rs b/src-tauri/yaak-models/src/models.rs index 623fe815f..1f5daf5ac 100644 --- a/src-tauri/yaak-models/src/models.rs +++ b/src-tauri/yaak-models/src/models.rs @@ -123,7 +123,7 @@ pub struct Settings { } impl UpsertModelInfo for Settings { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { SettingsIden::Table } @@ -252,7 +252,7 @@ pub struct Workspace { } impl UpsertModelInfo for Workspace { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { WorkspaceIden::Table } @@ -355,7 +355,7 @@ pub struct WorkspaceMeta { } impl UpsertModelInfo for WorkspaceMeta { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { WorkspaceMetaIden::Table } @@ -456,7 +456,7 @@ pub struct CookieJar { } impl UpsertModelInfo for CookieJar { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { CookieJarIden::Table } @@ -535,7 +535,7 @@ pub struct Environment { } impl UpsertModelInfo for Environment { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { EnvironmentIden::Table } @@ -655,7 +655,7 @@ pub struct Folder { } impl UpsertModelInfo for Folder { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { FolderIden::Table } @@ -786,7 +786,7 @@ pub struct HttpRequest { } impl UpsertModelInfo for HttpRequest { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { HttpRequestIden::Table } @@ -913,7 +913,7 @@ pub struct WebsocketConnection { } impl UpsertModelInfo for WebsocketConnection { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { WebsocketConnectionIden::Table } @@ -1027,7 +1027,7 @@ pub struct WebsocketRequest { } impl UpsertModelInfo for WebsocketRequest { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { WebsocketRequestIden::Table } @@ -1152,7 +1152,7 @@ pub struct WebsocketEvent { } impl UpsertModelInfo for WebsocketEvent { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { WebsocketEventIden::Table } @@ -1269,7 +1269,7 @@ pub struct HttpResponse { } impl UpsertModelInfo for HttpResponse { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { HttpResponseIden::Table } @@ -1377,7 +1377,7 @@ pub struct GraphQlIntrospection { } impl UpsertModelInfo for GraphQlIntrospection { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { GraphQlIntrospectionIden::Table } @@ -1461,7 +1461,7 @@ pub struct GrpcRequest { } impl UpsertModelInfo for GrpcRequest { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { GrpcRequestIden::Table } @@ -1588,7 +1588,7 @@ pub struct GrpcConnection { } impl UpsertModelInfo for GrpcConnection { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { GrpcConnectionIden::Table } @@ -1708,7 +1708,7 @@ pub struct GrpcEvent { } impl UpsertModelInfo for GrpcEvent { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { GrpcEventIden::Table } @@ -1799,7 +1799,7 @@ pub struct Plugin { } impl UpsertModelInfo for Plugin { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { PluginIden::Table } @@ -1881,7 +1881,7 @@ pub struct SyncState { } impl UpsertModelInfo for SyncState { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { SyncStateIden::Table } @@ -1964,7 +1964,7 @@ pub struct KeyValue { } impl UpsertModelInfo for KeyValue { - fn table_name() -> impl IntoTableRef + Debug { + fn table_name() -> impl IntoTableRef + IntoIden { KeyValueIden::Table } @@ -2181,7 +2181,7 @@ impl AnyModel { } pub trait UpsertModelInfo { - fn table_name() -> impl IntoTableRef + Debug; + fn table_name() -> impl IntoTableRef + IntoIden; fn id_column() -> impl IntoIden + Eq + Clone; fn generate_id() -> String; fn order_by() -> (impl IntoColumnRef, Order); diff --git a/src-tauri/yaak-models/src/queries/http_requests.rs b/src-tauri/yaak-models/src/queries/http_requests.rs index 0eff6bc43..021f9695b 100644 --- a/src-tauri/yaak-models/src/queries/http_requests.rs +++ b/src-tauri/yaak-models/src/queries/http_requests.rs @@ -64,7 +64,7 @@ impl<'a> DbContext<'a> { return self.resolve_auth_for_folder(&folder); } - let workspace = self.get_workspace("invalid")?; + let workspace = self.get_workspace(&http_request.workspace_id)?; Ok(self.resolve_auth_for_workspace(&workspace)) } From 36bbb87a5efa50caadae306e8e37cd854e4add0f Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 3 Jul 2025 11:48:17 -0700 Subject: [PATCH 293/996] Mostly working --- package-lock.json | 264 +++++--- package.json | 3 +- .../src/bindings/gen_events.ts | 162 +++-- .../src/plugins/ThemePlugin.ts | 9 +- .../plugin-runtime-types/src/plugins/index.ts | 2 +- packages/plugin-runtime-types/tsconfig.json | 9 +- packages/plugin-runtime/src/PluginInstance.ts | 9 + plugins/auth-basic/package.json | 2 +- plugins/auth-bearer/package.json | 2 +- plugins/auth-jwt/package.json | 2 +- plugins/auth-oauth2/package.json | 2 +- plugins/exporter-curl/package.json | 2 +- plugins/filter-jsonpath/package.json | 2 +- plugins/filter-xpath/package.json | 2 +- plugins/importer-curl/package.json | 2 +- plugins/importer-insomnia/package.json | 2 +- plugins/importer-openapi/package.json | 2 +- plugins/importer-postman/package.json | 2 +- plugins/importer-yaak/package.json | 2 +- plugins/template-function-cookie/package.json | 2 +- plugins/template-function-encode/package.json | 2 +- plugins/template-function-fs/package.json | 2 +- plugins/template-function-hash/package.json | 2 +- plugins/template-function-json/package.json | 2 +- plugins/template-function-prompt/package.json | 2 +- plugins/template-function-regex/package.json | 2 +- .../template-function-request/package.json | 2 +- .../template-function-response/package.json | 2 +- plugins/template-function-uuid/package.json | 2 +- plugins/template-function-uuid/src/index.ts | 2 +- plugins/template-function-xml/package.json | 2 +- plugins/template-function-xml/src/index.ts | 52 +- plugins/themes-yaak/package.json | 9 + plugins/themes-yaak/src/index.ts | 599 ++++++++++++++++++ src-tauri/Cargo.lock | 342 +++++----- src-tauri/Cargo.toml | 28 +- src-tauri/src/commands.rs | 17 +- src-tauri/src/lib.rs | 1 + src-tauri/yaak-plugins/bindings/gen_events.ts | 32 +- src-tauri/yaak-plugins/src/events.rs | 110 ++++ src-tauri/yaak-plugins/src/manager.rs | 26 +- src-web/components/GlobalHooks.tsx | 2 - src-web/components/Settings/SettingsTheme.tsx | 26 +- src-web/components/sidebar/SidebarItem.tsx | 2 +- src-web/hooks/useGenerateThemeCss.ts | 23 +- src-web/hooks/useResolvedTheme.ts | 24 +- src-web/lib/tauri.ts | 1 + src-web/lib/theme/themes.ts | 135 ++-- src-web/lib/theme/themes/catppuccin.ts | 156 ----- src-web/lib/theme/themes/dracula.ts | 29 - src-web/lib/theme/themes/github.ts | 52 -- src-web/lib/theme/themes/gruvbox.ts | 21 - src-web/lib/theme/themes/hotdog-stand.ts | 58 -- src-web/lib/theme/themes/monokai-pro.ts | 221 ------- src-web/lib/theme/themes/moonlight.ts | 64 -- src-web/lib/theme/themes/nord.ts | 30 - src-web/lib/theme/themes/relaxing.ts | 18 - src-web/lib/theme/themes/rose-pine.ts | 105 --- src-web/lib/theme/themes/yaak.ts | 74 --- src-web/lib/theme/window.ts | 330 +++++----- src-web/theme.ts | 6 +- 61 files changed, 1610 insertions(+), 1489 deletions(-) create mode 100644 plugins/themes-yaak/package.json create mode 100644 plugins/themes-yaak/src/index.ts delete mode 100644 src-web/lib/theme/themes/catppuccin.ts delete mode 100644 src-web/lib/theme/themes/dracula.ts delete mode 100644 src-web/lib/theme/themes/github.ts delete mode 100644 src-web/lib/theme/themes/gruvbox.ts delete mode 100644 src-web/lib/theme/themes/hotdog-stand.ts delete mode 100644 src-web/lib/theme/themes/monokai-pro.ts delete mode 100644 src-web/lib/theme/themes/moonlight.ts delete mode 100644 src-web/lib/theme/themes/nord.ts delete mode 100644 src-web/lib/theme/themes/relaxing.ts delete mode 100644 src-web/lib/theme/themes/rose-pine.ts delete mode 100644 src-web/lib/theme/themes/yaak.ts diff --git a/package-lock.json b/package-lock.json index f9462e8a5..6de2a014c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,7 +54,7 @@ "@eslint/compat": "^1.3.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "^9.29.0", - "@tauri-apps/cli": "2.4.1", + "@tauri-apps/cli": "^2.6.2", "@typescript-eslint/eslint-plugin": "^8.27.0", "@typescript-eslint/parser": "^8.27.0", "@yaakapp/cli": "^0.1.5", @@ -1146,17 +1146,20 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } @@ -2939,9 +2942,9 @@ } }, "node_modules/@tauri-apps/cli": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.4.1.tgz", - "integrity": "sha512-9Ta81jx9+57FhtU/mPIckDcOBtPTUdKM75t4+aA0X84b8Sclb0jy1xA8NplmcRzp2fsfIHNngU2NiRxsW5+yOQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.6.2.tgz", + "integrity": "sha512-s1/eyBHxk0wG1blLeOY2IDjgZcxVrkxU5HFL8rNDwjYGr0o7yr3RAtwmuUPhz13NO+xGAL1bJZaLFBdp+5joKg==", "dev": true, "license": "Apache-2.0 OR MIT", "bin": { @@ -2955,23 +2958,23 @@ "url": "https://opencollective.com/tauri" }, "optionalDependencies": { - "@tauri-apps/cli-darwin-arm64": "2.4.1", - "@tauri-apps/cli-darwin-x64": "2.4.1", - "@tauri-apps/cli-linux-arm-gnueabihf": "2.4.1", - "@tauri-apps/cli-linux-arm64-gnu": "2.4.1", - "@tauri-apps/cli-linux-arm64-musl": "2.4.1", - "@tauri-apps/cli-linux-riscv64-gnu": "2.4.1", - "@tauri-apps/cli-linux-x64-gnu": "2.4.1", - "@tauri-apps/cli-linux-x64-musl": "2.4.1", - "@tauri-apps/cli-win32-arm64-msvc": "2.4.1", - "@tauri-apps/cli-win32-ia32-msvc": "2.4.1", - "@tauri-apps/cli-win32-x64-msvc": "2.4.1" + "@tauri-apps/cli-darwin-arm64": "2.6.2", + "@tauri-apps/cli-darwin-x64": "2.6.2", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.6.2", + "@tauri-apps/cli-linux-arm64-gnu": "2.6.2", + "@tauri-apps/cli-linux-arm64-musl": "2.6.2", + "@tauri-apps/cli-linux-riscv64-gnu": "2.6.2", + "@tauri-apps/cli-linux-x64-gnu": "2.6.2", + "@tauri-apps/cli-linux-x64-musl": "2.6.2", + "@tauri-apps/cli-win32-arm64-msvc": "2.6.2", + "@tauri-apps/cli-win32-ia32-msvc": "2.6.2", + "@tauri-apps/cli-win32-x64-msvc": "2.6.2" } }, "node_modules/@tauri-apps/cli-darwin-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.4.1.tgz", - "integrity": "sha512-QME7s8XQwy3LWClTVlIlwXVSLKkeJ/z88pr917Mtn9spYOjnBfsgHAgGdmpWD3NfJxjg7CtLbhH49DxoFL+hLg==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.6.2.tgz", + "integrity": "sha512-YlvT+Yb7u2HplyN2Cf/nBplCQARC/I4uedlYHlgtxg6rV7xbo9BvG1jLOo29IFhqA2rOp5w1LtgvVGwsOf2kxw==", "cpu": [ "arm64" ], @@ -2986,9 +2989,9 @@ } }, "node_modules/@tauri-apps/cli-darwin-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.4.1.tgz", - "integrity": "sha512-/r89IcW6Ya1sEsFUEH7wLNruDTj7WmDWKGpPy7gATFtQr5JEY4heernqE82isjTUimnHZD8SCr0jA3NceI4ybw==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.6.2.tgz", + "integrity": "sha512-21gdPWfv1bP8rkTdCL44in70QcYcPaDM70L+y78N8TkBuC+/+wqnHcwwjzb+mUyck6UoEw2DORagSI/oKKUGJw==", "cpu": [ "x64" ], @@ -3003,9 +3006,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.4.1.tgz", - "integrity": "sha512-9tDijkRB+CchAGjXxYdY9l/XzFpLp1yihUtGXJz9eh+3qIoRI043n3e+6xmU8ZURr7XPnu+R4sCmXs6HD+NCEQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.6.2.tgz", + "integrity": "sha512-MW8Y6HqHS5yzQkwGoLk/ZyE1tWpnz/seDoY4INsbvUZdknuUf80yn3H+s6eGKtT/0Bfqon/W9sY7pEkgHRPQgA==", "cpu": [ "arm" ], @@ -3020,9 +3023,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm64-gnu": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.4.1.tgz", - "integrity": "sha512-pnFGDEXBAzS4iDYAVxTRhAzNu3K2XPGflYyBc0czfHDBXopqRgMyj5Q9Wj7HAwv6cM8BqzXINxnb2ZJFGmbSgA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.6.2.tgz", + "integrity": "sha512-9PdINTUtnyrnQt9hvC4y1m0NoxKSw/wUB9OTBAQabPj8WLAdvySWiUpEiqJjwLhlu4T6ltXZRpNTEzous3/RXg==", "cpu": [ "arm64" ], @@ -3037,9 +3040,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.1.tgz", - "integrity": "sha512-Hp0zXgeZNKmT+eoJSCxSBUm2QndNuRxR55tmIeNm3vbyUMJN/49uW7nurZ5fBPsacN4Pzwlx1dIMK+Gnr9A69w==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.6.2.tgz", + "integrity": "sha512-LrcJTRr7FrtQlTDkYaRXIGo/8YU/xkWmBPC646WwKNZ/S6yqCiDcOMoPe7Cx4ZvcG6sK6LUCLQMfaSNEL7PT0A==", "cpu": [ "arm64" ], @@ -3054,9 +3057,9 @@ } }, "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.4.1.tgz", - "integrity": "sha512-3T3bo2E4fdYRvzcXheWUeQOVB+LunEEi92iPRgOyuSVexVE4cmHYl+MPJF+EUV28Et0hIVTsHibmDO0/04lAFg==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.6.2.tgz", + "integrity": "sha512-GnTshO/BaZ9KGIazz2EiFfXGWgLur5/pjqklRA/ck42PGdUQJhV/Ao7A7TdXPjqAzpFxNo6M/Hx0GCH2iMS7IA==", "cpu": [ "riscv64" ], @@ -3071,9 +3074,9 @@ } }, "node_modules/@tauri-apps/cli-linux-x64-gnu": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.4.1.tgz", - "integrity": "sha512-kLN0FdNONO+2i+OpU9+mm6oTGufRC00e197TtwjpC0N6K2K8130w7Q3FeODIM2CMyg0ov3tH+QWqKW7GNhHFzg==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.6.2.tgz", + "integrity": "sha512-QDG3WeJD6UJekmrtVPCJRzlKgn9sGzhvD58oAw5gIU+DRovgmmG2U1jH9fS361oYGjWWO7d/KM9t0kugZzi4lQ==", "cpu": [ "x64" ], @@ -3088,9 +3091,9 @@ } }, "node_modules/@tauri-apps/cli-linux-x64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.1.tgz", - "integrity": "sha512-a8exvA5Ub9eg66a6hsMQKJIkf63QAf9OdiuFKOsEnKZkNN2x0NLgfvEcqdw88VY0UMs9dBoZ1AGbWMeYnLrLwQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.6.2.tgz", + "integrity": "sha512-TNVTDDtnWzuVqWBFdZ4+8ZTg17tc21v+CT5XBQ+KYCoYtCrIaHpW04fS5Tmudi+vYdBwoPDfwpKEB6LhCeFraQ==", "cpu": [ "x64" ], @@ -3105,9 +3108,9 @@ } }, "node_modules/@tauri-apps/cli-win32-arm64-msvc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.4.1.tgz", - "integrity": "sha512-4JFrslsMCJQG1c573T9uqQSAbF3j/tMKkMWzsIssv8jvPiP++OG61A2/F+y9te9/Q/O95cKhDK63kaiO5xQaeg==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.6.2.tgz", + "integrity": "sha512-z77C1oa/hMLO/jM1JF39tK3M3v9nou7RsBnQoOY54z5WPcpVAbS0XdFhXB7sSN72BOiO3moDky9lQANQz6L3CA==", "cpu": [ "arm64" ], @@ -3122,9 +3125,9 @@ } }, "node_modules/@tauri-apps/cli-win32-ia32-msvc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.4.1.tgz", - "integrity": "sha512-9eXfFORehYSCRwxg2KodfmX/mhr50CI7wyBYGbPLePCjr5z0jK/9IyW6r0tC+ZVjwpX48dkk7hKiUgI25jHjzA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.6.2.tgz", + "integrity": "sha512-TmD8BbzbjluBw8+QEIWUVmFa9aAluSkT1N937n1mpYLXcPbTpbunqRFiIznTwupoJNJIdtpF/t7BdZDRh5rrcg==", "cpu": [ "ia32" ], @@ -3139,9 +3142,9 @@ } }, "node_modules/@tauri-apps/cli-win32-x64-msvc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.4.1.tgz", - "integrity": "sha512-60a4Ov7Jrwqz2hzDltlS7301dhSAmM9dxo+IRBD3xz7yobKrgaHXYpWvnRomYItHcDd51VaKc9292H8/eE/gsw==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.6.2.tgz", + "integrity": "sha512-ItB8RCKk+nCmqOxOvbNtltz6x1A4QX6cSM21kj3NkpcnjT9rHSMcfyf8WVI2fkoMUJR80iqCblUX6ARxC3lj6w==", "cpu": [ "x64" ], @@ -3497,21 +3500,21 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.27.0.tgz", - "integrity": "sha512-4henw4zkePi5p252c8ncBLzLce52SEUz2Ebj8faDnuUXz2UuHEONYcJ+G0oaCF+bYCWVZtrGzq3FD7YXetmnSA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz", + "integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.27.0", - "@typescript-eslint/type-utils": "8.27.0", - "@typescript-eslint/utils": "8.27.0", - "@typescript-eslint/visitor-keys": "8.27.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/type-utils": "8.35.1", + "@typescript-eslint/utils": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "ignore": "^7.0.0", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3521,22 +3524,32 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "@typescript-eslint/parser": "^8.35.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/@typescript-eslint/parser": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.27.0.tgz", - "integrity": "sha512-XGwIabPallYipmcOk45DpsBSgLC64A0yvdAkrwEzwZ2viqGqRUJ8eEYoPz0CWnutgAFbNMPdsGGvzjSmcWVlEA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz", + "integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.27.0", - "@typescript-eslint/types": "8.27.0", - "@typescript-eslint/typescript-estree": "8.27.0", - "@typescript-eslint/visitor-keys": "8.27.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4" }, "engines": { @@ -3551,15 +3564,37 @@ "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz", + "integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.35.1", + "@typescript-eslint/types": "^8.35.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.27.0.tgz", - "integrity": "sha512-8oI9GwPMQmBryaaxG1tOZdxXVeMDte6NyJA4i7/TWa4fBwgnAXYlIQP+uYOeqAaLJ2JRxlG9CAyL+C+YE9Xknw==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.27.0", - "@typescript-eslint/visitor-keys": "8.27.0" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3569,17 +3604,34 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz", + "integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.27.0.tgz", - "integrity": "sha512-wVArTVcz1oJOIEJxui/nRhV0TXzD/zMSOYi/ggCfNq78EIszddXcJb7r4RCp/oBrjt8n9A0BSxRMKxHftpDxDA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz", + "integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.27.0", - "@typescript-eslint/utils": "8.27.0", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/utils": "8.35.1", "debug": "^4.3.4", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3594,9 +3646,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.27.0.tgz", - "integrity": "sha512-/6cp9yL72yUHAYq9g6DsAU+vVfvQmd1a8KyA81uvfDE21O2DwQ/qxlM4AR8TSdAu+kJLBDrEHKC5/W2/nxsY0A==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "license": "MIT", "engines": { @@ -3608,20 +3660,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.27.0.tgz", - "integrity": "sha512-BnKq8cqPVoMw71O38a1tEb6iebEgGA80icSxW7g+kndx0o6ot6696HjG7NdgfuAVmVEtwXUr3L8R9ZuVjoQL6A==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.27.0", - "@typescript-eslint/visitor-keys": "8.27.0", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3635,16 +3689,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.27.0.tgz", - "integrity": "sha512-njkodcwH1yvmo31YWgRHNb/x1Xhhq4/m81PhtvmRngD8iHPehxffz1SNCO+kwaePhATC+kOa/ggmvPoPza5i0Q==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz", + "integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.27.0", - "@typescript-eslint/types": "8.27.0", - "@typescript-eslint/typescript-estree": "8.27.0" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3659,14 +3713,14 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.27.0.tgz", - "integrity": "sha512-WsXQwMkILJvffP6z4U3FYJPlbf/j07HIxmDjZpbNvBJkMfvwXj5ACRkkHwBDvLBbDbtX5TdU64/rcvKJ/vuInQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.27.0", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3677,9 +3731,9 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -17550,7 +17604,7 @@ }, "packages/plugin-runtime-types": { "name": "@yaakapp/api", - "version": "0.6.4", + "version": "0.6.5", "dependencies": { "@types/node": "^22.5.4" }, diff --git a/package.json b/package.json index be616d6f1..130e78e20 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "plugins/template-function-response", "plugins/template-function-uuid", "plugins/template-function-xml", + "plugins/themes-yaak", "src-tauri/yaak-crypto", "src-tauri/yaak-git", "src-tauri/yaak-fonts", @@ -70,7 +71,7 @@ "@eslint/compat": "^1.3.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "^9.29.0", - "@tauri-apps/cli": "2.4.1", + "@tauri-apps/cli": "^2.6.2", "@typescript-eslint/eslint-plugin": "^8.27.0", "@typescript-eslint/parser": "^8.27.0", "@yaakapp/cli": "^0.1.5", diff --git a/packages/plugin-runtime-types/src/bindings/gen_events.ts b/packages/plugin-runtime-types/src/bindings/gen_events.ts index 001a58d03..f3400869e 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_events.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_events.ts @@ -12,7 +12,7 @@ export type CallHttpAuthenticationActionRequest = { index: number, pluginRefId: export type CallHttpAuthenticationRequest = { contextId: string, values: { [key in string]?: JsonPrimitive }, method: string, url: string, headers: Array, }; -export type CallHttpAuthenticationResponse = { +export type CallHttpAuthenticationResponse = { /** * HTTP headers to add to the request. Existing headers will be replaced, while * new headers will be added. @@ -53,7 +53,7 @@ export type ExportHttpRequestRequest = { httpRequest: HttpRequest, }; export type ExportHttpRequestResponse = { content: string, }; -export type FileFilter = { name: string, +export type FileFilter = { name: string, /** * File extensions to require */ @@ -73,176 +73,176 @@ export type FormInputAccordion = { label: string, inputs?: Array, hid export type FormInputBanner = { inputs?: Array, hidden?: boolean, color?: Color, }; -export type FormInputBase = { +export type FormInputBase = { /** * The name of the input. The value will be stored at this object attribute in the resulting data */ -name: string, +name: string, /** * Whether this input is visible for the given configuration. Use this to * make branching forms. */ -hidden?: boolean, +hidden?: boolean, /** * Whether the user must fill in the argument */ -optional?: boolean, +optional?: boolean, /** * The label of the input */ -label?: string, +label?: string, /** * Visually hide the label of the input */ -hideLabel?: boolean, +hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, +defaultValue?: string, disabled?: boolean, /** * Longer description of the input, likely shown in a tooltip */ description?: string, }; -export type FormInputCheckbox = { +export type FormInputCheckbox = { /** * The name of the input. The value will be stored at this object attribute in the resulting data */ -name: string, +name: string, /** * Whether this input is visible for the given configuration. Use this to * make branching forms. */ -hidden?: boolean, +hidden?: boolean, /** * Whether the user must fill in the argument */ -optional?: boolean, +optional?: boolean, /** * The label of the input */ -label?: string, +label?: string, /** * Visually hide the label of the input */ -hideLabel?: boolean, +hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, +defaultValue?: string, disabled?: boolean, /** * Longer description of the input, likely shown in a tooltip */ description?: string, }; -export type FormInputEditor = { +export type FormInputEditor = { /** * Placeholder for the text input */ -placeholder?: string | null, +placeholder?: string | null, /** * Don't show the editor gutter (line numbers, folds, etc.) */ -hideGutter?: boolean, +hideGutter?: boolean, /** * Language for syntax highlighting */ -language?: EditorLanguage, readOnly?: boolean, completionOptions?: Array, +language?: EditorLanguage, readOnly?: boolean, completionOptions?: Array, /** * The name of the input. The value will be stored at this object attribute in the resulting data */ -name: string, +name: string, /** * Whether this input is visible for the given configuration. Use this to * make branching forms. */ -hidden?: boolean, +hidden?: boolean, /** * Whether the user must fill in the argument */ -optional?: boolean, +optional?: boolean, /** * The label of the input */ -label?: string, +label?: string, /** * Visually hide the label of the input */ -hideLabel?: boolean, +hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, +defaultValue?: string, disabled?: boolean, /** * Longer description of the input, likely shown in a tooltip */ description?: string, }; -export type FormInputFile = { +export type FormInputFile = { /** * The title of the file selection window */ -title: string, +title: string, /** * Allow selecting multiple files */ -multiple?: boolean, directory?: boolean, defaultPath?: string, filters?: Array, +multiple?: boolean, directory?: boolean, defaultPath?: string, filters?: Array, /** * The name of the input. The value will be stored at this object attribute in the resulting data */ -name: string, +name: string, /** * Whether this input is visible for the given configuration. Use this to * make branching forms. */ -hidden?: boolean, +hidden?: boolean, /** * Whether the user must fill in the argument */ -optional?: boolean, +optional?: boolean, /** * The label of the input */ -label?: string, +label?: string, /** * Visually hide the label of the input */ -hideLabel?: boolean, +hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, +defaultValue?: string, disabled?: boolean, /** * Longer description of the input, likely shown in a tooltip */ description?: string, }; -export type FormInputHttpRequest = { +export type FormInputHttpRequest = { /** * The name of the input. The value will be stored at this object attribute in the resulting data */ -name: string, +name: string, /** * Whether this input is visible for the given configuration. Use this to * make branching forms. */ -hidden?: boolean, +hidden?: boolean, /** * Whether the user must fill in the argument */ -optional?: boolean, +optional?: boolean, /** * The label of the input */ -label?: string, +label?: string, /** * Visually hide the label of the input */ -hideLabel?: boolean, +hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, +defaultValue?: string, disabled?: boolean, /** * Longer description of the input, likely shown in a tooltip */ @@ -250,36 +250,36 @@ description?: string, }; export type FormInputMarkdown = { content: string, hidden?: boolean, }; -export type FormInputSelect = { +export type FormInputSelect = { /** * The options that will be available in the select input */ -options: Array, +options: Array, /** * The name of the input. The value will be stored at this object attribute in the resulting data */ -name: string, +name: string, /** * Whether this input is visible for the given configuration. Use this to * make branching forms. */ -hidden?: boolean, +hidden?: boolean, /** * Whether the user must fill in the argument */ -optional?: boolean, +optional?: boolean, /** * The label of the input */ -label?: string, +label?: string, /** * Visually hide the label of the input */ -hideLabel?: boolean, +hideLabel?: boolean, /** * The default value */ -defaultValue?: string, disabled?: boolean, +defaultValue?: string, disabled?: boolean, /** * Longer description of the input, likely shown in a tooltip */ @@ -287,44 +287,44 @@ description?: string, }; export type FormInputSelectOption = { label: string, value: string, }; -export type FormInputText = { +export type FormInputText = { /** * Placeholder for the text input */ -placeholder?: string | null, +placeholder?: string | null, /** * Placeholder for the text input */ -password?: boolean, +password?: boolean, /** * Whether to allow newlines in the input, like a