Compare commits

...

10 Commits

Author SHA1 Message Date
Gregory Schier
28bb460409 Add empty workspaces array to environment output fixture 2025-10-21 08:16:33 -07:00
Gregory Schier
56d635166b Add tsconfig.json for importer-postman-environment plugin 2025-10-21 08:08:27 -07:00
Gregory Schier
f6a7257104 Text color for selected 2025-10-21 07:46:55 -07:00
Gregory Schier
1fce060ef7 Npm i 2025-10-21 07:36:21 -07:00
Gregory Schier
5c966e5a95 Add bracket matching 2025-10-21 07:27:07 -07:00
Gregory Schier
0520ef5d43 Import postman environments
https://feedback.yaak.app/p/import-postman-environments
2025-10-21 07:20:37 -07:00
dependabot[bot]
25b110778a Bump vite from 7.0.7 to 7.0.8 (#269) 2025-10-20 21:19:55 -07:00
Gregory Schier
327bf84e57 Clarify proto import buttons 2025-10-20 09:23:12 -07:00
Gregory Schier
1c48b309b5 Fix indent guide hovering 2025-10-20 09:13:00 -07:00
Gregory Schier
7c5dec821d Remove React.lazy on overlay and tooltip 2025-10-19 12:00:30 -07:00
26 changed files with 515 additions and 270 deletions

17
package-lock.json generated
View File

@@ -25,6 +25,7 @@
"plugins/importer-insomnia", "plugins/importer-insomnia",
"plugins/importer-openapi", "plugins/importer-openapi",
"plugins/importer-postman", "plugins/importer-postman",
"plugins/importer-postman-environment",
"plugins/importer-yaak", "plugins/importer-yaak",
"plugins/template-function-cookie", "plugins/template-function-cookie",
"plugins/template-function-encode", "plugins/template-function-encode",
@@ -4189,6 +4190,10 @@
"resolved": "plugins/importer-postman", "resolved": "plugins/importer-postman",
"link": true "link": true
}, },
"node_modules/@yaak/importer-postman-environment": {
"resolved": "plugins/importer-postman-environment",
"link": true
},
"node_modules/@yaak/importer-yaak": { "node_modules/@yaak/importer-yaak": {
"resolved": "plugins/importer-yaak", "resolved": "plugins/importer-yaak",
"link": true "link": true
@@ -17852,9 +17857,9 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "7.0.7", "version": "7.0.8",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.0.7.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.8.tgz",
"integrity": "sha512-hc6LujN/EkJHmxeiDJMs0qBontZ1cdBvvoCbWhVjzUFTU329VRyOC46gHNSA8NcOC5yzCeXpwI40tieI3DEZqg==", "integrity": "sha512-cJBdq0/u+8rgstg9t7UkBilf8ipLmeXJO30NxD5HAHOivnj10ocV8YtR/XBvd2wQpN3TmcaxNKaHX3tN7o5F5A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -18882,6 +18887,10 @@
"name": "@yaak/importer-postman", "name": "@yaak/importer-postman",
"version": "0.1.0" "version": "0.1.0"
}, },
"plugins/importer-postman-environment": {
"name": "@yaak/importer-postman-environment",
"version": "0.1.0"
},
"plugins/importer-yaak": { "plugins/importer-yaak": {
"name": "@yaak/importer-yaak", "name": "@yaak/importer-yaak",
"version": "0.1.0" "version": "0.1.0"
@@ -19119,7 +19128,7 @@
"postcss": "^8.5.6", "postcss": "^8.5.6",
"postcss-nesting": "^13.0.2", "postcss-nesting": "^13.0.2",
"tailwindcss": "^3.4.17", "tailwindcss": "^3.4.17",
"vite": "^7.0.7", "vite": "^7.0.8",
"vite-plugin-static-copy": "^3.1.2", "vite-plugin-static-copy": "^3.1.2",
"vite-plugin-svgr": "^4.3.0", "vite-plugin-svgr": "^4.3.0",
"vite-plugin-top-level-await": "^1.5.0", "vite-plugin-top-level-await": "^1.5.0",

View File

@@ -24,6 +24,7 @@
"plugins/importer-insomnia", "plugins/importer-insomnia",
"plugins/importer-openapi", "plugins/importer-openapi",
"plugins/importer-postman", "plugins/importer-postman",
"plugins/importer-postman-environment",
"plugins/importer-yaak", "plugins/importer-yaak",
"plugins/template-function-cookie", "plugins/template-function-cookie",
"plugins/template-function-encode", "plugins/template-function-encode",

View File

@@ -0,0 +1,14 @@
{
"name": "@yaak/importer-postman-environment",
"displayName": "Postman Environment Importer",
"description": "Import environments from Postman",
"private": true,
"version": "0.1.0",
"main": "./build/index.js",
"scripts": {
"build": "yaakcli build",
"dev": "yaakcli dev",
"lint": "tsc --noEmit && eslint . --ext .ts,.tsx",
"test": "vitest --run tests"
}
}

View File

@@ -0,0 +1,138 @@
import type {
Context,
Environment,
PartialImportResources,
PluginDefinition,
Workspace,
} from '@yaakapp/api';
import type { ImportPluginResponse } from '@yaakapp/api/lib/plugins/ImporterPlugin';
type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
interface ExportResources {
workspaces: AtLeast<Workspace, 'name' | 'id' | 'model'>[];
environments: AtLeast<Environment, 'name' | 'id' | 'model' | 'workspaceId'>[];
}
export const plugin: PluginDefinition = {
importer: {
name: 'Postman Environment',
description: 'Import postman environment exports',
onImport(_ctx: Context, args: { text: string }) {
return convertPostmanEnvironment(args.text);
},
},
};
export function convertPostmanEnvironment(contents: string): ImportPluginResponse | undefined {
const root = parseJSONToRecord(contents);
if (root == null) return;
// Validate that it looks like a Postman Environment export
const values = toArray<{
key?: string;
value?: unknown;
enabled?: boolean;
description?: string;
type?: string;
}>(root.values);
const scope = root._postman_variable_scope;
const hasEnvMarkers = typeof scope === 'string';
if (values.length === 0 || (!hasEnvMarkers && typeof root.name !== 'string')) {
// Not a Postman environment file, skip
return;
}
const exportResources: ExportResources = {
workspaces: [],
environments: [],
};
const envVariables = values
.map((v) => ({
enabled: v.enabled ?? true,
name: String(v.key ?? ''),
value: String(v.value),
description: v.description ? String(v.description) : null,
}))
.filter((v) => v.name.length > 0);
const environment: ExportResources['environments'][0] = {
model: 'environment',
id: generateId('environment'),
name: root.name ? String(root.name) : 'Environment',
workspaceId: 'CURRENT_WORKSPACE',
parentModel: 'environment',
parentId: null,
variables: envVariables,
};
exportResources.environments.push(environment);
const resources = deleteUndefinedAttrs(
convertTemplateSyntax(exportResources),
) as PartialImportResources;
return { resources };
}
function parseJSONToRecord<T>(jsonStr: string): Record<string, T> | null {
try {
return toRecord(JSON.parse(jsonStr));
} catch {
return null;
}
}
function toRecord<T>(value: Record<string, T> | unknown): Record<string, T> {
if (value && typeof value === 'object' && !Array.isArray(value)) {
return value as Record<string, T>;
}
return {} as Record<string, T>;
}
function toArray<T>(value: unknown): T[] {
if (Object.prototype.toString.call(value) === '[object Array]') return value as T[];
else return [] as T[];
}
/** Recursively render all nested object properties */
function convertTemplateSyntax<T>(obj: T): T {
if (typeof obj === 'string') {
return obj.replace(
/{{\s*(_\.)?([^}]*)\s*}}/g,
(_m, _dot, expr) => '${[' + expr.trim() + ']}',
) 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 as Record<string, unknown>).map(([k, v]) => [k, convertTemplateSyntax(v)]),
) as T;
} else {
return obj;
}
}
function deleteUndefinedAttrs<T>(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 as Record<string, unknown>)
.filter(([, v]) => v !== undefined)
.map(([k, v]) => [k, deleteUndefinedAttrs(v)]),
) as T;
} else {
return obj;
}
}
const idCount: Partial<Record<string, number>> = {};
function generateId(model: string): string {
idCount[model] = (idCount[model] ?? -1) + 1;
return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`;
}
export default plugin;

View File

@@ -0,0 +1,27 @@
{
"id": "123",
"name": "My Environment",
"values": [
{
"key": "baseUrl",
"value": "https://api.example.com",
"type": "default",
"enabled": true
},
{
"key": "token",
"value": "{{ access_token }}",
"type": "default",
"description": "Access token for the API.",
"enabled": true
},
{
"key": "disabled",
"type": "secret",
"value": "hello",
"enabled": false
}
],
"_postman_variable_scope": "environment",
"_postman_exported_using": "PostmanRuntime/1.0.0"
}

View File

@@ -0,0 +1,35 @@
{
"resources": {
"workspaces": [],
"environments": [
{
"id": "GENERATE_ID::ENVIRONMENT_0",
"model": "environment",
"name": "My Environment",
"variables": [
{
"enabled": true,
"description": null,
"name": "baseUrl",
"value": "https://api.example.com"
},
{
"enabled": true,
"description": "Access token for the API.",
"name": "token",
"value": "${[access_token]}"
},
{
"enabled": false,
"description": null,
"name": "disabled",
"value": "hello"
}
],
"workspaceId": "CURRENT_WORKSPACE",
"parentId": null,
"parentModel": "environment"
}
]
}
}

View File

@@ -0,0 +1,22 @@
import * as fs from 'node:fs';
import * as path from 'node:path';
import { describe, expect, test } from 'vitest';
import { convertPostmanEnvironment } from '../src';
describe('importer-postman-environment', () => {
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 = convertPostmanEnvironment(contents);
expect(result).toEqual(JSON.parse(expected));
});
}
});

View File

@@ -0,0 +1,3 @@
{
"extends": "../../tsconfig.json"
}

View File

@@ -376,7 +376,7 @@ function toArray<T>(value: unknown): T[] {
/** Recursively render all nested object properties */ /** Recursively render all nested object properties */
function convertTemplateSyntax<T>(obj: T): T { function convertTemplateSyntax<T>(obj: T): T {
if (typeof obj === 'string') { if (typeof obj === 'string') {
return obj.replace(/{{\s*(_\.)?([^}]+)\s*}}/g, '${[$2]}') as T; return obj.replace(/{{\s*(_\.)?([^}]*)\s*}}/g, (_m, _dot, expr) => '${[' + expr.trim() + ']}') as T;
} else if (Array.isArray(obj) && obj != null) { } else if (Array.isArray(obj) && obj != null) {
return obj.map(convertTemplateSyntax) as T; return obj.map(convertTemplateSyntax) as T;
} else if (typeof obj === 'object' && obj != null) { } else if (typeof obj === 'object' && obj != null) {

291
src-tauri/Cargo.lock generated
View File

@@ -2,15 +2,6 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 4
[[package]]
name = "addr2line"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
dependencies = [
"gimli",
]
[[package]] [[package]]
name = "adler2" name = "adler2"
version = "2.0.0" version = "2.0.0"
@@ -85,12 +76,6 @@ dependencies = [
"alloc-no-stdlib", "alloc-no-stdlib",
] ]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]] [[package]]
name = "android_log-sys" name = "android_log-sys"
version = "0.3.2" version = "0.3.2"
@@ -428,21 +413,6 @@ dependencies = [
"tower-service", "tower-service",
] ]
[[package]]
name = "backtrace"
version = "0.3.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
dependencies = [
"addr2line",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
"windows-targets 0.52.6",
]
[[package]] [[package]]
name = "base32" name = "base32"
version = "0.5.1" version = "0.5.1"
@@ -717,7 +687,7 @@ dependencies = [
"semver", "semver",
"serde", "serde",
"serde_json", "serde_json",
"thiserror 2.0.12", "thiserror 2.0.17",
] ]
[[package]] [[package]]
@@ -816,17 +786,16 @@ dependencies = [
[[package]] [[package]]
name = "chrono" name = "chrono"
version = "0.4.41" version = "0.4.42"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
dependencies = [ dependencies = [
"android-tzdata",
"iana-time-zone", "iana-time-zone",
"js-sys", "js-sys",
"num-traits", "num-traits",
"serde", "serde",
"wasm-bindgen", "wasm-bindgen",
"windows-link", "windows-link 0.2.1",
] ]
[[package]] [[package]]
@@ -2002,12 +1971,6 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "gimli"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]] [[package]]
name = "gio" name = "gio"
version = "0.18.4" version = "0.18.4"
@@ -2405,7 +2368,7 @@ dependencies = [
"libc", "libc",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2 0.5.10",
"system-configuration", "system-configuration",
"tokio", "tokio",
"tower-service", "tower-service",
@@ -3205,7 +3168,7 @@ dependencies = [
"once_cell", "once_cell",
"png", "png",
"serde", "serde",
"thiserror 2.0.12", "thiserror 2.0.17",
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
@@ -3628,15 +3591,6 @@ dependencies = [
"objc2-security", "objc2-security",
] ]
[[package]]
name = "object"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.21.3" version = "1.21.3"
@@ -3782,7 +3736,7 @@ dependencies = [
"objc2-osa-kit", "objc2-osa-kit",
"serde", "serde",
"serde_json", "serde_json",
"thiserror 2.0.12", "thiserror 2.0.17",
] ]
[[package]] [[package]]
@@ -4334,8 +4288,8 @@ dependencies = [
"quinn-udp", "quinn-udp",
"rustc-hash", "rustc-hash",
"rustls", "rustls",
"socket2", "socket2 0.5.10",
"thiserror 2.0.12", "thiserror 2.0.17",
"tokio", "tokio",
"tracing", "tracing",
"web-time", "web-time",
@@ -4356,7 +4310,7 @@ dependencies = [
"rustls", "rustls",
"rustls-pki-types", "rustls-pki-types",
"slab", "slab",
"thiserror 2.0.12", "thiserror 2.0.17",
"tinyvec", "tinyvec",
"tracing", "tracing",
"web-time", "web-time",
@@ -4371,7 +4325,7 @@ dependencies = [
"cfg_aliases", "cfg_aliases",
"libc", "libc",
"once_cell", "once_cell",
"socket2", "socket2 0.5.10",
"tracing", "tracing",
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
@@ -4552,7 +4506,7 @@ checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
dependencies = [ dependencies = [
"getrandom 0.2.16", "getrandom 0.2.16",
"libredox", "libredox",
"thiserror 2.0.12", "thiserror 2.0.17",
] ]
[[package]] [[package]]
@@ -4766,12 +4720,6 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]] [[package]]
name = "rustc-hash" name = "rustc-hash"
version = "2.1.1" version = "2.1.1"
@@ -4815,9 +4763,9 @@ dependencies = [
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.23.27" version = "0.23.33"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" checksum = "751e04a496ca00bb97a5e043158d23d66b5aabf2e1d5aa2a0aaebb1aafe6f82c"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"ring", "ring",
@@ -4851,9 +4799,9 @@ dependencies = [
[[package]] [[package]]
name = "rustls-platform-verifier" name = "rustls-platform-verifier"
version = "0.6.0" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eda84358ed17f1f354cf4b1909ad346e6c7bc2513e8c40eb08e0157aa13a9070" checksum = "be59af91596cac372a6942530653ad0c3a246cdd491aaa9dcaee47f88d67d5a0"
dependencies = [ dependencies = [
"core-foundation 0.10.1", "core-foundation 0.10.1",
"core-foundation-sys", "core-foundation-sys",
@@ -4878,9 +4826,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
[[package]] [[package]]
name = "rustls-webpki" name = "rustls-webpki"
version = "0.103.3" version = "0.103.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf"
dependencies = [ dependencies = [
"ring", "ring",
"rustls-pki-types", "rustls-pki-types",
@@ -4981,7 +4929,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.101", "syn 2.0.101",
"thiserror 2.0.12", "thiserror 2.0.17",
] ]
[[package]] [[package]]
@@ -5065,9 +5013,9 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.226" version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [ dependencies = [
"serde_core", "serde_core",
"serde_derive", "serde_derive",
@@ -5107,18 +5055,18 @@ dependencies = [
[[package]] [[package]]
name = "serde_core" name = "serde_core"
version = "1.0.226" version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.226" version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -5138,14 +5086,15 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.140" version = "1.0.145"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
"ryu", "ryu",
"serde", "serde",
"serde_core",
] ]
[[package]] [[package]]
@@ -5392,6 +5341,16 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "socket2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
dependencies = [
"libc",
"windows-sys 0.60.2",
]
[[package]] [[package]]
name = "softbuffer" name = "softbuffer"
version = "0.4.6" version = "0.4.6"
@@ -5587,9 +5546,9 @@ dependencies = [
[[package]] [[package]]
name = "tao" name = "tao"
version = "0.34.3" version = "0.34.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "959469667dbcea91e5485fc48ba7dd6023face91bb0f1a14681a70f99847c3f7" checksum = "f3a753bdc39c07b192151523a3f77cd0394aa75413802c883a0f6f6a0e5ee2e7"
dependencies = [ dependencies = [
"bitflags 2.9.1", "bitflags 2.9.1",
"block2 0.6.1", "block2 0.6.1",
@@ -5661,9 +5620,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]] [[package]]
name = "tauri" name = "tauri"
version = "2.8.5" version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4d1d3b3dc4c101ac989fd7db77e045cc6d91a25349cd410455cb5c57d510c1c" checksum = "7f07c6590706b2fc0ab287b041cf5ce9c435b3850bdae5571e19d9d27584e89d"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@@ -5701,7 +5660,7 @@ dependencies = [
"tauri-runtime", "tauri-runtime",
"tauri-runtime-wry", "tauri-runtime-wry",
"tauri-utils", "tauri-utils",
"thiserror 2.0.12", "thiserror 2.0.17",
"tokio", "tokio",
"tray-icon", "tray-icon",
"url", "url",
@@ -5714,9 +5673,9 @@ dependencies = [
[[package]] [[package]]
name = "tauri-build" name = "tauri-build"
version = "2.4.1" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c432ccc9ff661803dab74c6cd78de11026a578a9307610bbc39d3c55be7943f" checksum = "f71be1f494b683ac439e6d61c16ab5c472c6f9c6ee78995b29556d9067c021a1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cargo_toml", "cargo_toml",
@@ -5736,9 +5695,9 @@ dependencies = [
[[package]] [[package]]
name = "tauri-codegen" name = "tauri-codegen"
version = "2.4.0" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ab3a62cf2e6253936a8b267c2e95839674e7439f104fa96ad0025e149d54d8a" checksum = "6c1fe64c74cc40f90848281a90058a6db931eb400b60205840e09801ee30f190"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"brotli", "brotli",
@@ -5754,7 +5713,7 @@ dependencies = [
"sha2", "sha2",
"syn 2.0.101", "syn 2.0.101",
"tauri-utils", "tauri-utils",
"thiserror 2.0.12", "thiserror 2.0.17",
"time", "time",
"url", "url",
"uuid", "uuid",
@@ -5763,9 +5722,9 @@ dependencies = [
[[package]] [[package]]
name = "tauri-macros" name = "tauri-macros"
version = "2.4.0" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4368ea8094e7045217edb690f493b55b30caf9f3e61f79b4c24b6db91f07995e" checksum = "260c5d2eb036b76206b9fca20b7be3614cfd21046c5396f7959e0e64a4b07f2f"
dependencies = [ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
@@ -5777,9 +5736,9 @@ dependencies = [
[[package]] [[package]]
name = "tauri-plugin" name = "tauri-plugin"
version = "2.4.0" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9946a3cede302eac0c6eb6c6070ac47b1768e326092d32efbb91f21ed58d978f" checksum = "3d7ce9aab979296b2f91e6fbf154207c2e3512b12ddca0b24bfa0e0cde6b2976"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"glob", "glob",
@@ -5804,7 +5763,7 @@ dependencies = [
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
] ]
[[package]] [[package]]
@@ -5821,7 +5780,7 @@ dependencies = [
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"tauri-utils", "tauri-utils",
"thiserror 2.0.12", "thiserror 2.0.17",
"tracing", "tracing",
"url", "url",
"windows-registry", "windows-registry",
@@ -5842,7 +5801,7 @@ dependencies = [
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"tauri-plugin-fs", "tauri-plugin-fs",
"thiserror 2.0.12", "thiserror 2.0.17",
"url", "url",
] ]
@@ -5863,7 +5822,7 @@ dependencies = [
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"tauri-utils", "tauri-utils",
"thiserror 2.0.12", "thiserror 2.0.17",
"toml 0.9.5", "toml 0.9.5",
"url", "url",
] ]
@@ -5886,7 +5845,7 @@ dependencies = [
"swift-rs", "swift-rs",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
"time", "time",
] ]
@@ -5906,7 +5865,7 @@ dependencies = [
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
"url", "url",
"windows", "windows",
"zbus", "zbus",
@@ -5927,7 +5886,7 @@ dependencies = [
"sys-locale", "sys-locale",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
] ]
[[package]] [[package]]
@@ -5947,7 +5906,7 @@ dependencies = [
"shared_child", "shared_child",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
"tokio", "tokio",
] ]
@@ -5961,7 +5920,7 @@ dependencies = [
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-plugin-deep-link", "tauri-plugin-deep-link",
"thiserror 2.0.12", "thiserror 2.0.17",
"tracing", "tracing",
"windows-sys 0.60.2", "windows-sys 0.60.2",
"zbus", "zbus",
@@ -5991,7 +5950,7 @@ dependencies = [
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"tempfile", "tempfile",
"thiserror 2.0.12", "thiserror 2.0.17",
"time", "time",
"tokio", "tokio",
"url", "url",
@@ -6011,14 +5970,14 @@ dependencies = [
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
] ]
[[package]] [[package]]
name = "tauri-runtime" name = "tauri-runtime"
version = "2.8.0" version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4cfc9ad45b487d3fded5a4731a567872a4812e9552e3964161b08edabf93846" checksum = "3367f0b47df90e9195cd9f04a56b0055a2cba45aa11923c6c253d748778176fc"
dependencies = [ dependencies = [
"cookie", "cookie",
"dpi", "dpi",
@@ -6032,7 +5991,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"tauri-utils", "tauri-utils",
"thiserror 2.0.12", "thiserror 2.0.17",
"url", "url",
"webkit2gtk", "webkit2gtk",
"webview2-com", "webview2-com",
@@ -6041,9 +6000,9 @@ dependencies = [
[[package]] [[package]]
name = "tauri-runtime-wry" name = "tauri-runtime-wry"
version = "2.8.1" version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1fe9d48bd122ff002064e88cfcd7027090d789c4302714e68fcccba0f4b7807" checksum = "80d91d29ca680c545364cf75ba2f2e3c7ea2ab6376bfa3be26b56fa2463a5b5e"
dependencies = [ dependencies = [
"gtk", "gtk",
"http", "http",
@@ -6068,9 +6027,9 @@ dependencies = [
[[package]] [[package]]
name = "tauri-utils" name = "tauri-utils"
version = "2.7.0" version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41a3852fdf9a4f8fbeaa63dc3e9a85284dd6ef7200751f0bd66ceee30c93f212" checksum = "f6b8bbe426abdbf52d050e52ed693130dbd68375b9ad82a3fb17efb4c8d85673"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"brotli", "brotli",
@@ -6096,7 +6055,7 @@ dependencies = [
"serde_json", "serde_json",
"serde_with", "serde_with",
"swift-rs", "swift-rs",
"thiserror 2.0.12", "thiserror 2.0.17",
"toml 0.9.5", "toml 0.9.5",
"url", "url",
"urlpattern", "urlpattern",
@@ -6159,11 +6118,11 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.12" version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
dependencies = [ dependencies = [
"thiserror-impl 2.0.12", "thiserror-impl 2.0.17",
] ]
[[package]] [[package]]
@@ -6179,9 +6138,9 @@ dependencies = [
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "2.0.12" version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -6268,27 +6227,26 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.45.1" version = "1.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
dependencies = [ dependencies = [
"backtrace",
"bytes", "bytes",
"libc", "libc",
"mio", "mio",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
"socket2", "socket2 0.6.1",
"tokio-macros", "tokio-macros",
"tracing", "tracing",
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
name = "tokio-macros" name = "tokio-macros"
version = "2.5.0" version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -6478,7 +6436,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pin-project", "pin-project",
"prost", "prost",
"socket2", "socket2 0.5.10",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tower 0.4.13", "tower 0.4.13",
@@ -6614,7 +6572,7 @@ dependencies = [
"once_cell", "once_cell",
"png", "png",
"serde", "serde",
"thiserror 2.0.12", "thiserror 2.0.17",
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
@@ -6645,21 +6603,21 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]] [[package]]
name = "ts-rs" name = "ts-rs"
version = "11.0.1" version = "11.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ef1b7a6d914a34127ed8e1fa927eb7088903787bcded4fa3eef8f85ee1568be" checksum = "4994acea2522cd2b3b85c1d9529a55991e3ad5e25cdcd3de9d505972c4379424"
dependencies = [ dependencies = [
"chrono", "chrono",
"serde_json", "serde_json",
"thiserror 2.0.12", "thiserror 2.0.17",
"ts-rs-macros", "ts-rs-macros",
] ]
[[package]] [[package]]
name = "ts-rs-macros" name = "ts-rs-macros"
version = "11.0.1" version = "11.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9d4ed7b4c18cc150a6a0a1e9ea1ecfa688791220781af6e119f9599a8502a0a" checksum = "ee6ff59666c9cbaec3533964505d39154dc4e0a56151fdea30a09ed0301f62e2"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -6682,7 +6640,7 @@ dependencies = [
"rustls", "rustls",
"rustls-pki-types", "rustls-pki-types",
"sha1", "sha1",
"thiserror 2.0.12", "thiserror 2.0.17",
"utf-8", "utf-8",
] ]
@@ -7204,7 +7162,7 @@ version = "0.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36695906a1b53a3bf5c4289621efedac12b73eeb0b89e7e1a89b517302d5d75c" checksum = "36695906a1b53a3bf5c4289621efedac12b73eeb0b89e7e1a89b517302d5d75c"
dependencies = [ dependencies = [
"thiserror 2.0.12", "thiserror 2.0.17",
"windows", "windows",
"windows-core", "windows-core",
] ]
@@ -7270,7 +7228,7 @@ dependencies = [
"windows-collections", "windows-collections",
"windows-core", "windows-core",
"windows-future", "windows-future",
"windows-link", "windows-link 0.1.1",
"windows-numerics", "windows-numerics",
] ]
@@ -7291,7 +7249,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [ dependencies = [
"windows-implement", "windows-implement",
"windows-interface", "windows-interface",
"windows-link", "windows-link 0.1.1",
"windows-result", "windows-result",
"windows-strings", "windows-strings",
] ]
@@ -7303,7 +7261,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
dependencies = [ dependencies = [
"windows-core", "windows-core",
"windows-link", "windows-link 0.1.1",
"windows-threading", "windows-threading",
] ]
@@ -7335,6 +7293,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]] [[package]]
name = "windows-numerics" name = "windows-numerics"
version = "0.2.0" version = "0.2.0"
@@ -7342,7 +7306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
dependencies = [ dependencies = [
"windows-core", "windows-core",
"windows-link", "windows-link 0.1.1",
] ]
[[package]] [[package]]
@@ -7351,7 +7315,7 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3bab093bdd303a1240bb99b8aba8ea8a69ee19d34c9e2ef9594e708a4878820" checksum = "b3bab093bdd303a1240bb99b8aba8ea8a69ee19d34c9e2ef9594e708a4878820"
dependencies = [ dependencies = [
"windows-link", "windows-link 0.1.1",
"windows-result", "windows-result",
"windows-strings", "windows-strings",
] ]
@@ -7362,7 +7326,7 @@ version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [ dependencies = [
"windows-link", "windows-link 0.1.1",
] ]
[[package]] [[package]]
@@ -7371,7 +7335,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [ dependencies = [
"windows-link", "windows-link 0.1.1",
] ]
[[package]] [[package]]
@@ -7410,6 +7374,15 @@ dependencies = [
"windows-targets 0.53.2", "windows-targets 0.53.2",
] ]
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link 0.2.1",
]
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.42.2" version = "0.42.2"
@@ -7478,7 +7451,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
dependencies = [ dependencies = [
"windows-link", "windows-link 0.1.1",
] ]
[[package]] [[package]]
@@ -7487,7 +7460,7 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e04a5c6627e310a23ad2358483286c7df260c964eb2d003d8efd6d0f4e79265c" checksum = "e04a5c6627e310a23ad2358483286c7df260c964eb2d003d8efd6d0f4e79265c"
dependencies = [ dependencies = [
"windows-link", "windows-link 0.1.1",
] ]
[[package]] [[package]]
@@ -7718,7 +7691,7 @@ dependencies = [
"os_pipe", "os_pipe",
"rustix 0.38.44", "rustix 0.38.44",
"tempfile", "tempfile",
"thiserror 2.0.12", "thiserror 2.0.17",
"tree_magic_mini", "tree_magic_mini",
"wayland-backend", "wayland-backend",
"wayland-client", "wayland-client",
@@ -7734,9 +7707,9 @@ checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
[[package]] [[package]]
name = "wry" name = "wry"
version = "0.53.3" version = "0.53.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31f0e9642a0d061f6236c54ccae64c2722a7879ad4ec7dff59bd376d446d8e90" checksum = "6d78ec082b80fa088569a970d043bb3050abaabf4454101d44514ee8d9a8c9f6"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"block2 0.6.1", "block2 0.6.1",
@@ -7766,7 +7739,7 @@ dependencies = [
"sha2", "sha2",
"soup3", "soup3",
"tao-macros", "tao-macros",
"thiserror 2.0.12", "thiserror 2.0.17",
"url", "url",
"webkit2gtk", "webkit2gtk",
"webkit2gtk-sys", "webkit2gtk-sys",
@@ -7865,7 +7838,7 @@ dependencies = [
"tauri-plugin-single-instance", "tauri-plugin-single-instance",
"tauri-plugin-updater", "tauri-plugin-updater",
"tauri-plugin-window-state", "tauri-plugin-window-state",
"thiserror 2.0.12", "thiserror 2.0.17",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"ts-rs", "ts-rs",
@@ -7894,7 +7867,7 @@ dependencies = [
"reqwest", "reqwest",
"serde", "serde",
"tauri", "tauri",
"thiserror 2.0.12", "thiserror 2.0.17",
] ]
[[package]] [[package]]
@@ -7909,7 +7882,7 @@ dependencies = [
"serde", "serde",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
"yaak-models", "yaak-models",
] ]
@@ -7921,7 +7894,7 @@ dependencies = [
"serde", "serde",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
"ts-rs", "ts-rs",
] ]
@@ -7937,7 +7910,7 @@ dependencies = [
"serde_yaml", "serde_yaml",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
"ts-rs", "ts-rs",
"yaak-models", "yaak-models",
"yaak-sync", "yaak-sync",
@@ -7991,7 +7964,7 @@ dependencies = [
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
"ts-rs", "ts-rs",
"yaak-common", "yaak-common",
"yaak-models", "yaak-models",
@@ -8030,9 +8003,9 @@ dependencies = [
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"tauri-plugin-dialog", "tauri-plugin-dialog",
"thiserror 2.0.12", "thiserror 2.0.17",
"tokio",
"ts-rs", "ts-rs",
"yaak-common",
] ]
[[package]] [[package]]
@@ -8057,7 +8030,7 @@ dependencies = [
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"tauri-plugin-shell", "tauri-plugin-shell",
"thiserror 2.0.12", "thiserror 2.0.17",
"tokio", "tokio",
"tokio-tungstenite", "tokio-tungstenite",
"ts-rs", "ts-rs",
@@ -8091,7 +8064,7 @@ dependencies = [
"sha1", "sha1",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
"tokio", "tokio",
"ts-rs", "ts-rs",
"yaak-models", "yaak-models",
@@ -8106,7 +8079,7 @@ dependencies = [
"serde", "serde",
"serde-wasm-bindgen", "serde-wasm-bindgen",
"serde_json", "serde_json",
"thiserror 2.0.12", "thiserror 2.0.17",
"tokio", "tokio",
"ts-rs", "ts-rs",
"wasm-bindgen", "wasm-bindgen",
@@ -8124,7 +8097,7 @@ dependencies = [
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"thiserror 2.0.12", "thiserror 2.0.17",
"tokio", "tokio",
"tokio-tungstenite", "tokio-tungstenite",
"yaak-http", "yaak-http",
@@ -8345,7 +8318,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aed5f10c571472911e37d8f7601a8dfba52b4f7f73a344015291b82ab292faf6" checksum = "aed5f10c571472911e37d8f7601a8dfba52b4f7f73a344015291b82ab292faf6"
dependencies = [ dependencies = [
"log", "log",
"thiserror 2.0.12", "thiserror 2.0.17",
"zip", "zip",
] ]

View File

@@ -37,7 +37,7 @@ updater = []
license = ["yaak-license"] license = ["yaak-license"]
[build-dependencies] [build-dependencies]
tauri-build = { version = "2.4.1", features = [] } tauri-build = { version = "2.5.0", features = [] }
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
openssl-sys = { version = "0.9.105", features = ["vendored"] } # For Ubuntu installation to work openssl-sys = { version = "0.9.105", features = ["vendored"] } # For Ubuntu installation to work
@@ -89,23 +89,23 @@ yaak-templates = { workspace = true }
yaak-ws = { path = "yaak-ws" } yaak-ws = { path = "yaak-ws" }
[workspace.dependencies] [workspace.dependencies]
chrono = "0.4.41" chrono = "0.4.42"
hex = "0.4.3" hex = "0.4.3"
keyring = "3.6.3" keyring = "3.6.3"
reqwest = "0.12.20" reqwest = "0.12.20"
reqwest_cookie_store = "0.8.0" reqwest_cookie_store = "0.8.0"
rustls = { version = "0.23.27", default-features = false } rustls = { version = "0.23.33", default-features = false }
rustls-platform-verifier = "0.6.0" rustls-platform-verifier = "0.6.1"
serde = "1.0.219" serde = "1.0.228"
serde_json = "1.0.140" serde_json = "1.0.145"
sha2 = "0.10.9" sha2 = "0.10.9"
tauri = "2.8.5" tauri = "2.9.0"
tauri-plugin = "2.4.0" tauri-plugin = "2.5.0"
tauri-plugin-dialog = "2.4.0" tauri-plugin-dialog = "2.4.0"
tauri-plugin-shell = "2.3.1" tauri-plugin-shell = "2.3.1"
thiserror = "2.0.12" thiserror = "2.0.17"
tokio = "1.45.1" tokio = "1.48.0"
ts-rs = "11.0.1" ts-rs = "11.1.0"
yaak-common = { path = "yaak-common" } yaak-common = { path = "yaak-common" }
yaak-crypto = { path = "yaak-crypto" } yaak-crypto = { path = "yaak-crypto" }
yaak-fonts = { path = "yaak-fonts" } yaak-fonts = { path = "yaak-fonts" }

View File

@@ -28,7 +28,7 @@ pub(crate) async fn import_data<R: Runtime>(
.workspaces .workspaces
.into_iter() .into_iter()
.map(|mut v| { .map(|mut v| {
v.id = maybe_gen_id::<Workspace>(v.id.as_str(), &mut id_map); v.id = maybe_gen_id::<Workspace, R>(window, v.id.as_str(), &mut id_map);
v v
}) })
.collect(); .collect();
@@ -37,11 +37,12 @@ pub(crate) async fn import_data<R: Runtime>(
.environments .environments
.into_iter() .into_iter()
.map(|mut v| { .map(|mut v| {
v.id = maybe_gen_id::<Environment>(v.id.as_str(), &mut id_map); v.id = maybe_gen_id::<Environment, R>(window, v.id.as_str(), &mut id_map);
v.workspace_id = maybe_gen_id::<Workspace>(v.workspace_id.as_str(), &mut id_map); v.workspace_id =
maybe_gen_id::<Workspace, R>(window, v.workspace_id.as_str(), &mut id_map);
match (v.parent_model.as_str(), v.parent_id.clone().as_deref()) { match (v.parent_model.as_str(), v.parent_id.clone().as_deref()) {
("folder", Some(parent_id)) => { ("folder", Some(parent_id)) => {
v.parent_id = Some(maybe_gen_id::<Folder>(&parent_id, &mut id_map)); v.parent_id = Some(maybe_gen_id::<Folder, R>(window, &parent_id, &mut id_map));
} }
("", _) => { ("", _) => {
// Fix any empty ones // Fix any empty ones
@@ -60,9 +61,10 @@ pub(crate) async fn import_data<R: Runtime>(
.folders .folders
.into_iter() .into_iter()
.map(|mut v| { .map(|mut v| {
v.id = maybe_gen_id::<Folder>(v.id.as_str(), &mut id_map); v.id = maybe_gen_id::<Folder, R>(window, v.id.as_str(), &mut id_map);
v.workspace_id = maybe_gen_id::<Workspace>(v.workspace_id.as_str(), &mut id_map); v.workspace_id =
v.folder_id = maybe_gen_id_opt::<Folder>(v.folder_id, &mut id_map); maybe_gen_id::<Workspace, R>(window, v.workspace_id.as_str(), &mut id_map);
v.folder_id = maybe_gen_id_opt::<Folder, R>(window, v.folder_id, &mut id_map);
v v
}) })
.collect(); .collect();
@@ -71,9 +73,10 @@ pub(crate) async fn import_data<R: Runtime>(
.http_requests .http_requests
.into_iter() .into_iter()
.map(|mut v| { .map(|mut v| {
v.id = maybe_gen_id::<HttpRequest>(v.id.as_str(), &mut id_map); v.id = maybe_gen_id::<HttpRequest, R>(window, v.id.as_str(), &mut id_map);
v.workspace_id = maybe_gen_id::<Workspace>(v.workspace_id.as_str(), &mut id_map); v.workspace_id =
v.folder_id = maybe_gen_id_opt::<Folder>(v.folder_id, &mut id_map); maybe_gen_id::<Workspace, R>(window, v.workspace_id.as_str(), &mut id_map);
v.folder_id = maybe_gen_id_opt::<Folder, R>(window, v.folder_id, &mut id_map);
v v
}) })
.collect(); .collect();
@@ -82,9 +85,10 @@ pub(crate) async fn import_data<R: Runtime>(
.grpc_requests .grpc_requests
.into_iter() .into_iter()
.map(|mut v| { .map(|mut v| {
v.id = maybe_gen_id::<GrpcRequest>(v.id.as_str(), &mut id_map); v.id = maybe_gen_id::<GrpcRequest, R>(window, v.id.as_str(), &mut id_map);
v.workspace_id = maybe_gen_id::<Workspace>(v.workspace_id.as_str(), &mut id_map); v.workspace_id =
v.folder_id = maybe_gen_id_opt::<Folder>(v.folder_id, &mut id_map); maybe_gen_id::<Workspace, R>(window, v.workspace_id.as_str(), &mut id_map);
v.folder_id = maybe_gen_id_opt::<Folder, R>(window, v.folder_id, &mut id_map);
v v
}) })
.collect(); .collect();
@@ -93,9 +97,10 @@ pub(crate) async fn import_data<R: Runtime>(
.websocket_requests .websocket_requests
.into_iter() .into_iter()
.map(|mut v| { .map(|mut v| {
v.id = maybe_gen_id::<WebsocketRequest>(v.id.as_str(), &mut id_map); v.id = maybe_gen_id::<WebsocketRequest, R>(window, v.id.as_str(), &mut id_map);
v.workspace_id = maybe_gen_id::<Workspace>(v.workspace_id.as_str(), &mut id_map); v.workspace_id =
v.folder_id = maybe_gen_id_opt::<Folder>(v.folder_id, &mut id_map); maybe_gen_id::<Workspace, R>(window, v.workspace_id.as_str(), &mut id_map);
v.folder_id = maybe_gen_id_opt::<Folder, R>(window, v.folder_id, &mut id_map);
v v
}) })
.collect(); .collect();

View File

@@ -22,8 +22,8 @@ sha2 = { workspace = true }
tauri = { workspace = true } tauri = { workspace = true }
tauri-plugin-dialog = { workspace = true } tauri-plugin-dialog = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
tokio = { workspace = true }
ts-rs = { workspace = true, features = ["chrono-impl", "serde-json-impl"] } ts-rs = { workspace = true, features = ["chrono-impl", "serde-json-impl"] }
yaak-common = { workspace = true }
[build-dependencies] [build-dependencies]
tauri-plugin = { workspace = true, features = ["build"] } tauri-plugin = { workspace = true, features = ["build"] }

View File

@@ -3,6 +3,7 @@ use crate::models::{
AnyModel, Environment, Folder, GrpcRequest, HttpRequest, UpsertModelInfo, WebsocketRequest, AnyModel, Environment, Folder, GrpcRequest, HttpRequest, UpsertModelInfo, WebsocketRequest,
Workspace, WorkspaceIden, Workspace, WorkspaceIden,
}; };
use yaak_common::window::WorkspaceWindowTrait;
use crate::query_manager::QueryManagerExt; use crate::query_manager::QueryManagerExt;
use chrono::{NaiveDateTime, Utc}; use chrono::{NaiveDateTime, Utc};
use log::warn; use log::warn;
@@ -158,7 +159,17 @@ pub fn get_workspace_export_resources<R: Runtime>(
Ok(data) Ok(data)
} }
pub fn maybe_gen_id<M: UpsertModelInfo>(id: &str, ids: &mut BTreeMap<String, String>) -> String { pub fn maybe_gen_id<M: UpsertModelInfo, R: Runtime>(
window: &WebviewWindow<R>,
id: &str,
ids: &mut BTreeMap<String, String>,
) -> String {
if id == "CURRENT_WORKSPACE" {
if let Some(wid) = window.workspace_id() {
return wid.to_string();
}
}
if !id.starts_with("GENERATE_ID::") { if !id.starts_with("GENERATE_ID::") {
return id.to_string(); return id.to_string();
} }
@@ -173,12 +184,13 @@ pub fn maybe_gen_id<M: UpsertModelInfo>(id: &str, ids: &mut BTreeMap<String, Str
} }
} }
pub fn maybe_gen_id_opt<M: UpsertModelInfo>( pub fn maybe_gen_id_opt<M: UpsertModelInfo, R: Runtime>(
window: &WebviewWindow<R>,
id: Option<String>, id: Option<String>,
ids: &mut BTreeMap<String, String>, ids: &mut BTreeMap<String, String>,
) -> Option<String> { ) -> Option<String> {
match id { match id {
Some(id) => Some(maybe_gen_id::<M>(id.as_str(), ids)), Some(id) => Some(maybe_gen_id::<M, R>(window, id.as_str(), ids)),
None => None, None => None,
} }
} }

View File

@@ -6,7 +6,7 @@ use reqwest::{Response, Url};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::path::Path; use std::path::Path;
use std::str::FromStr; use std::str::FromStr;
use tauri::{AppHandle, Runtime, is_dev}; use tauri::{AppHandle, Runtime};
use ts_rs::TS; use ts_rs::TS;
use yaak_common::api_client::yaak_api_client; use yaak_common::api_client::yaak_api_client;
use yaak_models::query_manager::QueryManagerExt; use yaak_models::query_manager::QueryManagerExt;

View File

@@ -60,7 +60,7 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
await grpc.reflect.refetch(); await grpc.reflect.refetch();
}} }}
> >
Add Files Add Proto Files
</Button> </Button>
<Button <Button
variant="border" variant="border"
@@ -76,7 +76,7 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
await grpc.reflect.refetch(); await grpc.reflect.refetch();
}} }}
> >
Add Directories Add Import Folders
</Button> </Button>
<Button <Button
isLoading={grpc.reflect.isFetching} isLoading={grpc.reflect.isFetching}

View File

@@ -1,11 +1,10 @@
import classNames from 'classnames'; import classNames from 'classnames';
import { FocusTrap } from 'focus-trap-react';
import * as m from 'motion/react-m'; import * as m from 'motion/react-m';
import type { ReactNode} from 'react'; import type { ReactNode } from 'react';
import React, { Suspense , lazy, useRef } from 'react'; import React, { useRef } from 'react';
import { Portal } from './Portal'; import { Portal } from './Portal';
const FocusTrap = lazy(() => import('focus-trap-react'));
interface Props { interface Props {
children: ReactNode; children: ReactNode;
portalName: string; portalName: string;
@@ -51,52 +50,50 @@ export function Overlay({
return ( return (
<Portal name={portalName}> <Portal name={portalName}>
{open && ( {open && (
<Suspense> <FocusTrap
<FocusTrap focusTrapOptions={{
focusTrapOptions={{ allowOutsideClick: true, // So we can still click toasts and things
allowOutsideClick: true, // So we can still click toasts and things delayInitialFocus: true,
delayInitialFocus: true, fallbackFocus: () => containerRef.current!, // always have a target
fallbackFocus: () => containerRef.current!, // always have a target initialFocus: () =>
initialFocus: () => // Doing this explicitly seems to work better than the default behavior for some reason
// Doing this explicitly seems to work better than the default behavior for some reason containerRef.current?.querySelector<HTMLElement>(
containerRef.current?.querySelector<HTMLElement>( [
[ 'a[href]',
'a[href]', 'input:not([disabled])',
'input:not([disabled])', 'select:not([disabled])',
'select:not([disabled])', 'textarea:not([disabled])',
'textarea:not([disabled])', 'button:not([disabled])',
'button:not([disabled])', '[tabindex]:not([tabindex="-1"])',
'[tabindex]:not([tabindex="-1"])', '[contenteditable]:not([contenteditable="false"])',
'[contenteditable]:not([contenteditable="false"])', ].join(', '),
].join(', '), ) ?? undefined,
) ?? undefined, }}
}} >
<m.div
ref={containerRef}
tabIndex={-1}
className={classNames('fixed inset-0', zIndexes[zIndex])}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
> >
<m.div <div
ref={containerRef} aria-hidden
tabIndex={-1} onClick={onClose}
className={classNames('fixed inset-0', zIndexes[zIndex])} className={classNames(
initial={{ opacity: 0 }} 'absolute inset-0',
animate={{ opacity: 1 }} variant === 'default' && 'bg-backdrop backdrop-blur-sm',
>
<div
aria-hidden
onClick={onClose}
className={classNames(
'absolute inset-0',
variant === 'default' && 'bg-backdrop backdrop-blur-sm',
)}
/>
{/* Show the draggable region at the top */}
{/* TODO: Figure out tauri drag region and also make clickable still */}
{variant === 'default' && (
<div data-tauri-drag-region className="absolute top-0 left-0 h-md right-0" />
)} )}
{children} />
</m.div>
</FocusTrap> {/* Show the draggable region at the top */}
</Suspense> {/* TODO: Figure out tauri drag region and also make clickable still */}
{variant === 'default' && (
<div data-tauri-drag-region className="absolute top-0 left-0 h-md right-0" />
)}
{children}
</m.div>
</FocusTrap>
)} )}
</Portal> </Portal>
); );

View File

@@ -19,6 +19,11 @@
@apply text-surface !important; @apply text-surface !important;
} }
/* Matching bracket */
.cm-matchingBracket {
@apply bg-transparent border-b border-b-text-subtle;
}
&:not(.cm-focused) { &:not(.cm-focused) {
.cm-cursor, .cm-fat-cursor { .cm-cursor, .cm-fat-cursor {
@apply hidden; @apply hidden;

View File

@@ -10,7 +10,7 @@ import { json } from '@codemirror/lang-json';
import { markdown } from '@codemirror/lang-markdown'; import { markdown } from '@codemirror/lang-markdown';
import { xml } from '@codemirror/lang-xml'; import { xml } from '@codemirror/lang-xml';
import type { LanguageSupport } from '@codemirror/language'; import type { LanguageSupport } from '@codemirror/language';
import { import { bracketMatching ,
codeFolding, codeFolding,
foldGutter, foldGutter,
foldKeymap, foldKeymap,
@@ -258,6 +258,7 @@ export const multiLineExtensions = ({ hideGutter }: { hideGutter?: boolean }) =>
indentOnInput(), indentOnInput(),
rectangularSelection(), rectangularSelection(),
crosshairCursor(), crosshairCursor(),
bracketMatching(),
highlightActiveLineGutter(), highlightActiveLineGutter(),
keymap.of([...searchKeymap, ...foldKeymap, ...lintKeymap]), keymap.of([...searchKeymap, ...foldKeymap, ...lintKeymap]),
]; ];

View File

@@ -1,17 +1,8 @@
import classNames from 'classnames'; import classNames from 'classnames';
import type { import type { CSSProperties, KeyboardEvent, ReactNode } from 'react';
CSSProperties, import React, { useRef, useState } from 'react';
KeyboardEvent,
ReactNode} from 'react';
import React, {
lazy,
Suspense,
useRef,
useState,
} from 'react';
import { generateId } from '../../lib/generateId'; import { generateId } from '../../lib/generateId';
import { Portal } from '../Portal';
const Portal = lazy(() => import('../Portal').then((m) => ({ default: m.Portal })));
export interface TooltipProps { export interface TooltipProps {
children: ReactNode; children: ReactNode;
@@ -75,7 +66,7 @@ export function Tooltip({ children, content, tabIndex, size = 'md' }: TooltipPro
const id = useRef(`tooltip-${generateId()}`); const id = useRef(`tooltip-${generateId()}`);
return ( return (
<Suspense> <>
<Portal name="tooltip"> <Portal name="tooltip">
<div <div
ref={tooltipRef} ref={tooltipRef}
@@ -114,7 +105,7 @@ export function Tooltip({ children, content, tabIndex, size = 'md' }: TooltipPro
> >
{children} {children}
</span> </span>
</Suspense> </>
); );
} }

View File

@@ -466,6 +466,7 @@ function TreeInner<T extends { id: string }>(
> >
<div <div
className={classNames( className={classNames(
'[&_.tree-item.selected_.tree-item-inner]:text-text',
'[&:focus-within]:[&_.tree-item.selected]:bg-surface-active', '[&:focus-within]:[&_.tree-item.selected]:bg-surface-active',
'[&:not(:focus-within)]:[&_.tree-item.selected]:bg-surface-highlight', '[&:not(:focus-within)]:[&_.tree-item.selected]:bg-surface-highlight',

View File

@@ -1,16 +1,19 @@
import classNames from 'classnames'; import classNames from 'classnames';
import { useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
import { memo } from 'react'; import { memo } from 'react';
import { hoveredParentDepthFamily } from './atoms'; import { hoveredParentDepthFamily, isParentHoveredFamily } from './atoms';
export const TreeIndentGuide = memo(function TreeIndentGuide({ export const TreeIndentGuide = memo(function TreeIndentGuide({
treeId, treeId,
depth, depth,
parentId,
}: { }: {
treeId: string; treeId: string;
depth: number; depth: number;
parentId: string | null;
}) { }) {
const parentDepth = useAtomValue(hoveredParentDepthFamily(treeId)); const parentDepth = useAtomValue(hoveredParentDepthFamily(treeId));
const isHovered = useAtomValue(isParentHoveredFamily({ treeId, parentId }));
return ( return (
<div className="flex"> <div className="flex">
@@ -19,7 +22,7 @@ export const TreeIndentGuide = memo(function TreeIndentGuide({
key={i} key={i}
className={classNames( className={classNames(
'w-[1rem] border-r border-r-text-subtlest', 'w-[1rem] border-r border-r-text-subtlest',
parentDepth !== i + 1 && 'opacity-30', !(parentDepth === i + 1 && isHovered) && 'opacity-30',
)} )}
/> />
))} ))}

View File

@@ -239,7 +239,7 @@ function TreeItem_<T extends { id: string }>({
isSelected && 'selected', isSelected && 'selected',
)} )}
> >
<TreeIndentGuide treeId={treeId} depth={depth} /> <TreeIndentGuide treeId={treeId} depth={depth} parentId={node.parent?.item.id ?? null} />
<div <div
className={classNames( className={classNames(
'text-text-subtle', 'text-text-subtle',
@@ -275,7 +275,7 @@ function TreeItem_<T extends { id: string }>({
onClick={handleClick} onClick={handleClick}
onDoubleClick={handleDoubleClick} onDoubleClick={handleDoubleClick}
disabled={editing} disabled={editing}
className="px-2 focus:outline-none flex items-center gap-2 h-full whitespace-nowrap" className="tree-item-inner px-2 focus:outline-none flex items-center gap-2 h-full whitespace-nowrap"
{...attributes} {...attributes}
{...listeners} {...listeners}
tabIndex={isLastSelected ? 0 : -1} tabIndex={isLastSelected ? 0 : -1}

View File

@@ -45,8 +45,14 @@ export const hoveredParentFamily = atomFamily((_treeId: string) => {
}); });
}); });
export const isParentHoveredFamily = atomFamily(
({ treeId, parentId }: { treeId: string; parentId: string | null }) =>
selectAtom(hoveredParentFamily(treeId), (v) => v.parentId === parentId, Object.is),
(a, b) => a.treeId === b.treeId && a.parentId === b.parentId,
);
export const isIndexHoveredFamily = atomFamily( export const isIndexHoveredFamily = atomFamily(
({ treeId, index }: { treeId: string; index: number}) => ({ treeId, index }: { treeId: string; index: number }) =>
selectAtom(hoveredParentFamily(treeId), (v) => v.index === index, Object.is), selectAtom(hoveredParentFamily(treeId), (v) => v.index === index, Object.is),
(a, b) => a.treeId === b.treeId && a.index === b.index, (a, b) => a.treeId === b.treeId && a.index === b.index,
); );
@@ -55,8 +61,8 @@ export const hoveredParentDepthFamily = atomFamily((treeId: string) =>
selectAtom( selectAtom(
hoveredParentFamily(treeId), hoveredParentFamily(treeId),
(s) => s.parentDepth, (s) => s.parentDepth,
(a, b) => Object.is(a, b) // prevents re-render unless the value changes (a, b) => Object.is(a, b), // prevents re-render unless the value changes
) ),
); );
export const collapsedFamily = atomFamily((workspaceId: string) => { export const collapsedFamily = atomFamily((workspaceId: string) => {

View File

@@ -67,7 +67,9 @@ async function performImport(filePath: string): Promise<boolean> {
return ( return (
<VStack space={3} className="pb-4"> <VStack space={3} className="pb-4">
<ul className="list-disc pl-6"> <ul className="list-disc pl-6">
<li>{pluralizeCount('Workspace', imported.workspaces.length)}</li> {imported.workspaces.length > 0 && (
<li>{pluralizeCount('Workspace', imported.workspaces.length)}</li>
)}
{imported.environments.length > 0 && ( {imported.environments.length > 0 && (
<li>{pluralizeCount('Environment', imported.environments.length)}</li> <li>{pluralizeCount('Environment', imported.environments.length)}</li>
)} )}

View File

@@ -90,7 +90,7 @@
"postcss": "^8.5.6", "postcss": "^8.5.6",
"postcss-nesting": "^13.0.2", "postcss-nesting": "^13.0.2",
"tailwindcss": "^3.4.17", "tailwindcss": "^3.4.17",
"vite": "^7.0.7", "vite": "^7.0.8",
"vite-plugin-static-copy": "^3.1.2", "vite-plugin-static-copy": "^3.1.2",
"vite-plugin-svgr": "^4.3.0", "vite-plugin-svgr": "^4.3.0",
"vite-plugin-top-level-await": "^1.5.0", "vite-plugin-top-level-await": "^1.5.0",