From aa60ea14d30f0a7d8de9c1528a5b632c470628f9 Mon Sep 17 00:00:00 2001 From: Ken Snyder Date: Mon, 14 Feb 2022 12:52:27 -0800 Subject: [PATCH] chore(tauri-search): started setting up for AST parse of rust --- packages/docs/package.json | 12 +- packages/docs/pnpm-global/5/pnpm-lock.yaml | 4 - packages/docs/src/App.vue | 6 +- packages/docs/src/components/Footer.vue | 15 + packages/docs/src/components/SearchHit.vue | 172 ++-- packages/docs/vite.config.ts | 4 +- packages/scraper/Cargo.toml | 8 + packages/scraper/src/main.rs | 3 + packages/tauri-search/package.json | 21 +- packages/tauri-search/src/constants.ts | 3 +- .../api/tauri-docs_dev/ts-documents.json | 2 +- .../prose/tauri-docs_dev/documents.json | 2 +- .../src/generated/repos/documents.json | 2 +- .../src/generated/sitemap-tauri-docs-dev.json | 2 +- .../src/mappers/ConsolidatedMapper.ts | 85 +- .../mappers/consolidated/ApiToConsolidated.ts | 32 + .../consolidated/ProseToConsolidated.ts | 31 + .../consolidated/RepoToConsolidated.ts | 32 + .../src/mappers/consolidated/index.ts | 3 + .../src/models/ConsolidatedModel.ts | 48 +- .../tauri-search/test/ast/parseRust.test.ts | 28 +- .../test/ast/parseTypescript.test.ts | 2 +- .../{rust-docs.json => rust-ast.json} | 0 pnpm-lock.yaml | 803 +++++++++++------- tauri-search.code-workspace | 4 + 25 files changed, 828 insertions(+), 496 deletions(-) delete mode 100644 packages/docs/pnpm-global/5/pnpm-lock.yaml create mode 100644 packages/scraper/Cargo.toml create mode 100644 packages/scraper/src/main.rs create mode 100644 packages/tauri-search/src/mappers/consolidated/ApiToConsolidated.ts create mode 100644 packages/tauri-search/src/mappers/consolidated/ProseToConsolidated.ts create mode 100644 packages/tauri-search/src/mappers/consolidated/RepoToConsolidated.ts create mode 100644 packages/tauri-search/src/mappers/consolidated/index.ts rename packages/tauri-search/test/fixtures/{rust-docs.json => rust-ast.json} (100%) diff --git a/packages/docs/package.json b/packages/docs/package.json index a25a61d..a2d3849 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -25,7 +25,6 @@ "floating-vue": "^2.0.0-beta.6", "inferred-types": "^0.18.4", "markdown-it-expandable": "^1.0.2", - "meili-searchbar": "^2.1.0", "nprogress": "^0.2.0", "pinia": "^2.0.11", "prism-theme-vars": "^0.2.2", @@ -37,7 +36,7 @@ }, "devDependencies": { "@antfu/eslint-config": "^0.16.1", - "@iconify/json": "^2.0.35", + "@iconify/json": "^2.0.36", "@intlify/vite-plugin-vue-i18n": "^3.2.2", "@types/markdown-it-link-attributes": "^3.0.1", "@types/nprogress": "^0.2.0", @@ -48,26 +47,27 @@ "critters": "^0.0.16", "cross-env": "^7.0.3", "dotenv": "^16.0.0", - "eslint": "^8.8.0", + "eslint": "^8.9.0", "eslint-plugin-cypress": "^2.12.1", "https-localhost": "^4.7.0", "jsdom": "^19.0.0", "markdown-it": "^12.3.2", "markdown-it-link-attributes": "^4.0.0", "markdown-it-prism": "^2.2.2", + "meili-searchbar": "^2.2.1", "typescript": "^4.5.5", "unplugin-auto-import": "^0.5.11", "unplugin-icons": "^0.13.1", "unplugin-vue-components": "^0.17.18", - "vite": "^2.8.0", - "vite-plugin-inspect": "^0.3.13", + "vite": "^2.8.1", + "vite-plugin-inspect": "^0.3.14", "vite-plugin-md": "^0.11.8", "vite-plugin-pages": "^0.20.2", "vite-plugin-pwa": "^0.11.13", "vite-plugin-vue-layouts": "^0.6.0", "vite-plugin-windicss": "^1.7.0", "vite-ssg": "^0.17.10", - "vitest": "^0.3.0", + "vitest": "^0.3.2", "vue-tsc": "^0.31.2" } } diff --git a/packages/docs/pnpm-global/5/pnpm-lock.yaml b/packages/docs/pnpm-global/5/pnpm-lock.yaml deleted file mode 100644 index ff1d217..0000000 --- a/packages/docs/pnpm-global/5/pnpm-lock.yaml +++ /dev/null @@ -1,4 +0,0 @@ -lockfileVersion: 5.3 - -specifiers: - meili-searchbar: ^2.1.0 diff --git a/packages/docs/src/App.vue b/packages/docs/src/App.vue index 413f1f9..fb302e6 100644 --- a/packages/docs/src/App.vue +++ b/packages/docs/src/App.vue @@ -3,10 +3,8 @@ // you can use this to manipulate the document head in any components, // they will be rendered correctly in the html results with vite-ssg useHead({ - title: "Vitesse", - meta: [ - { name: "description", content: "Opinionated Vite Starter Template" }, - ], + title: "Tauri Search", + meta: [{ name: "description", content: "documentation for Tauri's search" }], }); diff --git a/packages/docs/src/components/Footer.vue b/packages/docs/src/components/Footer.vue index 450291e..231a8e1 100644 --- a/packages/docs/src/components/Footer.vue +++ b/packages/docs/src/components/Footer.vue @@ -1,8 +1,17 @@ \ No newline at end of file + + diff --git a/packages/docs/vite.config.ts b/packages/docs/vite.config.ts index f50fef8..af3a398 100644 --- a/packages/docs/vite.config.ts +++ b/packages/docs/vite.config.ts @@ -127,8 +127,8 @@ export default defineConfig({ registerType: "autoUpdate", includeAssets: ["favicon.svg", "robots.txt", "safari-pinned-tab.svg"], manifest: { - name: "Vitesse", - short_name: "Vitesse", + name: "Tauri Search", + short_name: "Search", theme_color: "#ffffff", icons: [ { diff --git a/packages/scraper/Cargo.toml b/packages/scraper/Cargo.toml new file mode 100644 index 0000000..31b2d68 --- /dev/null +++ b/packages/scraper/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "scraper" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/packages/scraper/src/main.rs b/packages/scraper/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/packages/scraper/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/packages/tauri-search/package.json b/packages/tauri-search/package.json index a2a2bb0..e51809d 100644 --- a/packages/tauri-search/package.json +++ b/packages/tauri-search/package.json @@ -37,7 +37,8 @@ "restart": "docker compose restart", "sitemap": "node bin/sitemap.cjs", "test": "vitest run", - "test:watch": "vitest watch --ui", + "test:watch": "vitest", + "test:ui": "vitest watch --ui --silent", "ts-ast": "node ./bin/ts-ast.cjs", "ts-ast-overview": "node ./bin/ts-ast-overview.cjs", "watch": "run-p watch:*", @@ -52,19 +53,19 @@ "gray-matter": "^4.0.3", "html-to-text": "^8.1.0", "inferred-types": "^0.18.4", - "native-dash": "^1.21.5", + "native-dash": "^1.22.0", "simple-markdown-2": "^0.7.5" }, "devDependencies": { "@octokit/types": "^6.34.0", "@type-challenges/utils": "^0.1.1", "@types/markdown-it": "^12.2.3", - "@types/node": "^14.18.10", - "@typescript-eslint/eslint-plugin": "^5.11.0", - "@typescript-eslint/parser": "^5.11.0", - "@vitest/ui": "^0.3.0", + "@types/node": "^14.18.12", + "@typescript-eslint/eslint-plugin": "^5.12.0", + "@typescript-eslint/parser": "^5.12.0", + "@vitest/ui": "^0.3.5", "changeset": "^0.2.6", - "eslint": "^8.8.0", + "eslint": "^8.9.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-cypress": "^2.12.1", "eslint-plugin-import": "^2.25.4", @@ -78,10 +79,10 @@ "ts-node": "^10.5.0", "tsup": "^5.11.13", "typescript": "^4.5.5", - "vite": "^2.8.0", + "vite": "^2.8.2", "vite-plugin-dts": "^0.9.9", - "vite-plugin-inspect": "^0.3.13", - "vitest": "^0.3.0" + "vite-plugin-inspect": "^0.3.14", + "vitest": "^0.3.5" }, "engines": { "node": ">=14", diff --git a/packages/tauri-search/src/constants.ts b/packages/tauri-search/src/constants.ts index ed7e78f..f7d8541 100644 --- a/packages/tauri-search/src/constants.ts +++ b/packages/tauri-search/src/constants.ts @@ -2,13 +2,12 @@ import { Stage } from "~/types"; export const TAURI_BASE_URL = `https://tauri.studio`; export const TAURI_JS_DOCS_URL = `${TAURI_BASE_URL}/docs/api/js`; - export const GITHUB_API_BASE = `https://api.github.com`; - export const REPO_DOCS_CACHE = `src/generated/ast/repo/documents.json`; export const TS_DOCS_CACHE = `src/generated/ast/api/ts-documents.json`; export const TS_AST_CACHE = `src/generated/ast/api/ts-ast.json`; +export const RUST_AST_FIXTURE = `test/fixtures/rust-ast.json`; export const RS_DOCS_CACHE = `src/generated/ast/api/rs-documents.json`; export const SERVERS: Record = { diff --git a/packages/tauri-search/src/generated/api/tauri-docs_dev/ts-documents.json b/packages/tauri-search/src/generated/api/tauri-docs_dev/ts-documents.json index da1f7ba..0637a08 100644 --- a/packages/tauri-search/src/generated/api/tauri-docs_dev/ts-documents.json +++ b/packages/tauri-search/src/generated/api/tauri-docs_dev/ts-documents.json @@ -1 +1 @@ -[{"id":"ts_app_Namespace_app","name":"app","kind":"Namespace","module":"app","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.app` when `tauri.conf.json > build > withGlobalTauri` is set to true.","declaration":"Module app","url":"https://tauri.studio/docs/api/js/modules/app#app"},{"id":"ts_app_Function_getName","name":"getName","kind":"Function","module":"app","language":"typescript","declaration":"function getName(getName: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/app#getName"},{"id":"ts_app_Function_getTauriVersion","name":"getTauriVersion","kind":"Function","module":"app","language":"typescript","declaration":"function getTauriVersion(getTauriVersion: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/app#getTauriVersion"},{"id":"ts_app_Function_getVersion","name":"getVersion","kind":"Function","module":"app","language":"typescript","declaration":"function getVersion(getVersion: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/app#getVersion"},{"id":"ts_cli_Namespace_cli","name":"cli","kind":"Namespace","module":"cli","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.cli` when `tauri.conf.json > build > withGlobalTauri` is set to true.","declaration":"Module cli","url":"https://tauri.studio/docs/api/js/modules/cli#cli"},{"id":"ts_cli_Interface_ArgMatch","name":"ArgMatch","kind":"Interface","module":"cli","language":"typescript","declaration":"interface ArgMatch {\n\toccurrences,\n\tvalue\n}","url":"https://tauri.studio/docs/api/js/modules/cli#ArgMatch"},{"id":"ts_cli_Interface_CliMatches","name":"CliMatches","kind":"Interface","module":"cli","language":"typescript","declaration":"interface CliMatches {\n\targs,\n\tsubcommand\n}","url":"https://tauri.studio/docs/api/js/modules/cli#CliMatches"},{"id":"ts_cli_Interface_SubcommandMatch","name":"SubcommandMatch","kind":"Interface","module":"cli","language":"typescript","declaration":"interface SubcommandMatch {\n\tmatches,\n\tname\n}","url":"https://tauri.studio/docs/api/js/modules/cli#SubcommandMatch"},{"id":"ts_cli_Function_getMatches","name":"getMatches","kind":"Function","module":"cli","language":"typescript","declaration":"function getMatches(getMatches: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/cli#getMatches"},{"id":"ts_clipboard_Namespace_clipboard","name":"clipboard","kind":"Namespace","module":"clipboard","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.clipboard` when `tauri.conf.json > build > withGlobalTauri` is set to true.","declaration":"Module clipboard","url":"https://tauri.studio/docs/api/js/modules/clipboard#clipboard"},{"id":"ts_clipboard_Function_readText","name":"readText","kind":"Function","module":"clipboard","language":"typescript","declaration":"function readText(readText: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/clipboard#readText"},{"id":"ts_clipboard_Function_writeText","name":"writeText","kind":"Function","module":"clipboard","language":"typescript","declaration":"function writeText(writeText: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/clipboard#writeText"},{"id":"ts_dialog_Namespace_dialog","name":"dialog","kind":"Namespace","module":"dialog","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.dialog` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n\nThe APIs must be allowlisted on `tauri.conf.json`:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"dialog\": {\n \"all\": true, // enable all dialog APIs\n \"open\": true, // enable file open API\n \"save\": true // enable file save API\n }\n }\n }\n}\n```\nIt is recommended to allowlist only the APIs you use for optimal bundle size and security.","declaration":"Module dialog","url":"https://tauri.studio/docs/api/js/modules/dialog#dialog"},{"id":"ts_dialog_Interface_DialogFilter","name":"DialogFilter","kind":"Interface","module":"dialog","language":"typescript","declaration":"interface DialogFilter {\n\textensions,\n\tname\n}","url":"https://tauri.studio/docs/api/js/modules/dialog#DialogFilter"},{"id":"ts_dialog_Interface_OpenDialogOptions","name":"OpenDialogOptions","kind":"Interface","module":"dialog","language":"typescript","declaration":"interface OpenDialogOptions {\n\tdefaultPath,\n\tdirectory,\n\tfilters,\n\tmultiple,\n\ttitle\n}","url":"https://tauri.studio/docs/api/js/modules/dialog#OpenDialogOptions"},{"id":"ts_dialog_Interface_SaveDialogOptions","name":"SaveDialogOptions","kind":"Interface","module":"dialog","language":"typescript","declaration":"interface SaveDialogOptions {\n\tdefaultPath,\n\tfilters,\n\ttitle\n}","url":"https://tauri.studio/docs/api/js/modules/dialog#SaveDialogOptions"},{"id":"ts_dialog_Function_ask","name":"ask","kind":"Function","module":"dialog","language":"typescript","declaration":"function ask(ask: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/dialog#ask"},{"id":"ts_dialog_Function_confirm","name":"confirm","kind":"Function","module":"dialog","language":"typescript","declaration":"function confirm(confirm: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/dialog#confirm"},{"id":"ts_dialog_Function_message","name":"message","kind":"Function","module":"dialog","language":"typescript","declaration":"function message(message: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/dialog#message"},{"id":"ts_dialog_Function_open","name":"open","kind":"Function","module":"dialog","language":"typescript","declaration":"function open(open: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/dialog#open"},{"id":"ts_dialog_Function_save","name":"save","kind":"Function","module":"dialog","language":"typescript","declaration":"function save(save: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/dialog#save"},{"id":"ts_event_Namespace_event","name":"event","kind":"Namespace","module":"event","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.event` when `tauri.conf.json > build > withGlobalTauri` is set to true.","declaration":"Module event","url":"https://tauri.studio/docs/api/js/modules/event#event"},{"id":"ts_event_Interface_Event","name":"Event","kind":"Interface","module":"event","language":"typescript","declaration":"interface Event {\n\tevent,\n\tid,\n\tpayload,\n\twindowLabel\n}","url":"https://tauri.studio/docs/api/js/modules/event#Event"},{"id":"ts_event_Type_alias_EventCallback","name":"EventCallback","kind":"Type alias","module":"event","language":"typescript","type":{"type":"reflection","declaration":{"id":69,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"helpers/event.ts","line":39,"character":31}],"signatures":[{"id":70,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":71,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":61,"typeArguments":[{"type":"reference","id":72,"name":"T"}],"name":"Event"}}],"type":{"type":"intrinsic","name":"void"}}]}},"declaration":"Type alias EventCallback","url":"https://tauri.studio/docs/api/js/modules/event#EventCallback"},{"id":"ts_event_Type_alias_EventName","name":"EventName","kind":"Type alias","module":"event","language":"typescript","type":{"type":"reference","typeArguments":[{"type":"union","types":[{"type":"literal","value":"tauri://update"},{"type":"literal","value":"tauri://update-available"},{"type":"literal","value":"tauri://update-install"},{"type":"literal","value":"tauri://update-status"},{"type":"literal","value":"tauri://resize"},{"type":"literal","value":"tauri://move"},{"type":"literal","value":"tauri://close-requested"},{"type":"literal","value":"tauri://focus"},{"type":"literal","value":"tauri://blur"},{"type":"literal","value":"tauri://scale-change"},{"type":"literal","value":"tauri://menu"},{"type":"literal","value":"tauri://file-drop"},{"type":"literal","value":"tauri://file-drop-hover"},{"type":"literal","value":"tauri://file-drop-cancelled"}]},{"type":"intrinsic","name":"string"}],"qualifiedName":"LiteralUnion","package":"type-fest","name":"LiteralUnion"},"declaration":"Type alias EventName","url":"https://tauri.studio/docs/api/js/modules/event#EventName"},{"id":"ts_event_Type_alias_UnlistenFn","name":"UnlistenFn","kind":"Type alias","module":"event","language":"typescript","type":{"type":"reflection","declaration":{"id":74,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"helpers/event.ts","line":41,"character":25}],"signatures":[{"id":75,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}]}},"declaration":"Type alias UnlistenFn","url":"https://tauri.studio/docs/api/js/modules/event#UnlistenFn"},{"id":"ts_event_Function_emit","name":"emit","kind":"Function","module":"event","language":"typescript","declaration":"function emit(emit: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/event#emit"},{"id":"ts_event_Function_listen","name":"listen","kind":"Function","module":"event","language":"typescript","declaration":"function listen(listen: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/event#listen"},{"id":"ts_event_Function_once","name":"once","kind":"Function","module":"event","language":"typescript","declaration":"function once(once: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/event#once"},{"id":"ts_fs_Namespace_fs","name":"fs","kind":"Namespace","module":"fs","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.fs` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n\nThe APIs must be allowlisted on `tauri.conf.json`:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"fs\": {\n \"all\": true, // enable all FS APIs\n \"readFile\": true,\n \"writeFile\": true,\n \"readDir\": true,\n \"copyFile\": true,\n \"createDir\": true,\n \"removeDir\": true,\n \"removeFile\": true,\n \"renameFile\": true\n }\n }\n }\n}\n```\nIt is recommended to allowlist only the APIs you use for optimal bundle size and security.\n\n## Security\n\nThis module prevents path traversal, not allowing absolute paths or parent dir components\n(i.e. \"/usr/path/to/file\" or \"../path/to/file\" paths are not allowed).\nPaths accessed with this API must be relative to one of the [[BaseDirectory | base directories]]\nso if you need access to arbitrary filesystem paths, you must write such logic on the core layer instead.\n\nThe API has a scope configuration that forces you to restrict the paths that can be accessed using glob patterns.\n\nThe scope configuration is an array of glob patterns describing folder paths that are allowed.\nFor instance, this scope configuration only allows accessing files on the\n*databases* folder of the [[path.appDir | $APP directory]]:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"fs\": {\n \"scope\": [\"$APP/databases/*\"]\n }\n }\n }\n}\n```\n\nNotice the use of the `$APP` variable. The value is injected at runtime, resolving to the [[path.appDir | app directory]].\nThe available variables are:\n[[path.audioDir | `$AUDIO`]], [[path.cacheDir | `$CACHE`]], [[path.configDir | `$CONFIG`]], [[path.dataDir | `$DATA`]],\n[[path.localDataDir | `$LOCALDATA`]], [[path.desktopDir | `$DESKTOP`]], [[path.documentDir | `$DOCUMENT`]],\n[[path.downloadDir | `$DOWNLOAD`]], [[path.executableDir | `$EXE`]], [[path.fontDir | `$FONT`]], [[path.homeDir | `$HOME`]],\n[[path.pictureDir | `$PICTURE`]], [[path.publicDir | `$PUBLIC`]], [[path.runtimeDir | `$RUNTIME`]],\n[[path.templateDir | `$TEMPLATE`]], [[path.videoDir | `$VIDEO`]], [[path.resourceDir | `$RESOURCE`]], [[path.appDir | `$APP`]].\n\nTrying to execute any API with a URL not configured on the scope results in a promise rejection due to denied access.\n\nNote that this scope applies to **all** APIs on this module.\n","declaration":"Module fs","url":"https://tauri.studio/docs/api/js/modules/fs#fs"},{"id":"ts_fs_Reference_Dir","name":"Dir","kind":"Reference","module":"fs","language":"typescript","declaration":"type Dir = {\n\tundefined\n}","url":"https://tauri.studio/docs/api/js/modules/fs#Dir"},{"id":"ts_fs_Enumeration_BaseDirectory","name":"BaseDirectory","kind":"Enumeration","module":"fs","language":"typescript","declaration":"enum BaseDirectory {\n\tApp,\n\tAudio,\n\tCache,\n\tConfig,\n\tData,\n\tDesktop,\n\tDocument,\n\tDownload,\n\tExecutable,\n\tFont,\n\tHome,\n\tLocalData,\n\tLog,\n\tPicture,\n\tPublic,\n\tResource,\n\tRuntime,\n\tTemplate,\n\tVideo\n}","url":"https://tauri.studio/docs/api/js/modules/fs#BaseDirectory"},{"id":"ts_fs_Interface_FileEntry","name":"FileEntry","kind":"Interface","module":"fs","language":"typescript","declaration":"interface FileEntry {\n\tchildren,\n\tname,\n\tpath\n}","url":"https://tauri.studio/docs/api/js/modules/fs#FileEntry"},{"id":"ts_fs_Interface_FsBinaryFileOption","name":"FsBinaryFileOption","kind":"Interface","module":"fs","language":"typescript","declaration":"interface FsBinaryFileOption {\n\tcontents,\n\tpath\n}","url":"https://tauri.studio/docs/api/js/modules/fs#FsBinaryFileOption"},{"id":"ts_fs_Interface_FsDirOptions","name":"FsDirOptions","kind":"Interface","module":"fs","language":"typescript","declaration":"interface FsDirOptions {\n\tdir,\n\trecursive\n}","url":"https://tauri.studio/docs/api/js/modules/fs#FsDirOptions"},{"id":"ts_fs_Interface_FsOptions","name":"FsOptions","kind":"Interface","module":"fs","language":"typescript","declaration":"interface FsOptions {\n\tdir\n}","url":"https://tauri.studio/docs/api/js/modules/fs#FsOptions"},{"id":"ts_fs_Interface_FsTextFileOption","name":"FsTextFileOption","kind":"Interface","module":"fs","language":"typescript","declaration":"interface FsTextFileOption {\n\tcontents,\n\tpath\n}","url":"https://tauri.studio/docs/api/js/modules/fs#FsTextFileOption"},{"id":"ts_fs_Function_copyFile","name":"copyFile","kind":"Function","module":"fs","language":"typescript","declaration":"function copyFile(copyFile: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/fs#copyFile"},{"id":"ts_fs_Function_createDir","name":"createDir","kind":"Function","module":"fs","language":"typescript","declaration":"function createDir(createDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/fs#createDir"},{"id":"ts_fs_Function_readBinaryFile","name":"readBinaryFile","kind":"Function","module":"fs","language":"typescript","declaration":"function readBinaryFile(readBinaryFile: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/fs#readBinaryFile"},{"id":"ts_fs_Function_readDir","name":"readDir","kind":"Function","module":"fs","language":"typescript","declaration":"function readDir(readDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/fs#readDir"},{"id":"ts_fs_Function_readTextFile","name":"readTextFile","kind":"Function","module":"fs","language":"typescript","declaration":"function readTextFile(readTextFile: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/fs#readTextFile"},{"id":"ts_fs_Function_removeDir","name":"removeDir","kind":"Function","module":"fs","language":"typescript","declaration":"function removeDir(removeDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/fs#removeDir"},{"id":"ts_fs_Function_removeFile","name":"removeFile","kind":"Function","module":"fs","language":"typescript","declaration":"function removeFile(removeFile: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/fs#removeFile"},{"id":"ts_fs_Function_renameFile","name":"renameFile","kind":"Function","module":"fs","language":"typescript","declaration":"function renameFile(renameFile: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/fs#renameFile"},{"id":"ts_fs_Function_writeBinaryFile","name":"writeBinaryFile","kind":"Function","module":"fs","language":"typescript","declaration":"function writeBinaryFile(writeBinaryFile: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/fs#writeBinaryFile"},{"id":"ts_fs_Function_writeFile","name":"writeFile","kind":"Function","module":"fs","language":"typescript","declaration":"function writeFile(writeFile: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/fs#writeFile"},{"id":"ts_globalShortcut_Namespace_globalShortcut","name":"globalShortcut","kind":"Namespace","module":"globalShortcut","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.globalShortcut` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n\nThe APIs must be allowlisted on `tauri.conf.json`:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"globalShortcut\": {\n \"all\": true // enable all global shortcut APIs\n }\n }\n }\n}\n```\nIt is recommended to allowlist only the APIs you use for optimal bundle size and security.","declaration":"Module globalShortcut","url":"https://tauri.studio/docs/api/js/modules/globalShortcut#globalShortcut"},{"id":"ts_globalShortcut_Type_alias_ShortcutHandler","name":"ShortcutHandler","kind":"Type alias","module":"globalShortcut","language":"typescript","type":{"type":"reflection","declaration":{"id":171,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"globalShortcut.ts","line":29,"character":30}],"signatures":[{"id":172,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":173,"name":"shortcut","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"void"}}]}},"declaration":"Type alias ShortcutHandler","url":"https://tauri.studio/docs/api/js/modules/globalShortcut#ShortcutHandler"},{"id":"ts_globalShortcut_Function_isRegistered","name":"isRegistered","kind":"Function","module":"globalShortcut","language":"typescript","declaration":"function isRegistered(isRegistered: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/globalShortcut#isRegistered"},{"id":"ts_globalShortcut_Function_register","name":"register","kind":"Function","module":"globalShortcut","language":"typescript","declaration":"function register(register: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/globalShortcut#register"},{"id":"ts_globalShortcut_Function_registerAll","name":"registerAll","kind":"Function","module":"globalShortcut","language":"typescript","declaration":"function registerAll(registerAll: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/globalShortcut#registerAll"},{"id":"ts_globalShortcut_Function_unregister","name":"unregister","kind":"Function","module":"globalShortcut","language":"typescript","declaration":"function unregister(unregister: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/globalShortcut#unregister"},{"id":"ts_globalShortcut_Function_unregisterAll","name":"unregisterAll","kind":"Function","module":"globalShortcut","language":"typescript","declaration":"function unregisterAll(unregisterAll: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/globalShortcut#unregisterAll"},{"id":"ts_http_Namespace_http","name":"http","kind":"Namespace","module":"http","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.http` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n\nThe APIs must be allowlisted on `tauri.conf.json`:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"http\": {\n \"all\": true, // enable all http APIs\n \"request\": true // enable HTTP request API\n }\n }\n }\n}\n```\nIt is recommended to allowlist only the APIs you use for optimal bundle size and security.\n\n## Security\n\nThis API has a scope configuration that forces you to restrict the URLs and paths that can be accessed using glob patterns.\n\nFor instance, this scope configuration only allows making HTTP requests to the GitHub API for the `tauri-apps` organization:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"http\": {\n \"scope\": [\"https://api.github.com/repos/tauri-apps/*\"]\n }\n }\n }\n}\n```\nTrying to execute any API with a URL not configured on the scope results in a promise rejection due to denied access.\n","declaration":"Module http","url":"https://tauri.studio/docs/api/js/modules/http#http"},{"id":"ts_http_Enumeration_ResponseType","name":"ResponseType","kind":"Enumeration","module":"http","language":"typescript","declaration":"enum ResponseType {\n\tBinary,\n\tJSON,\n\tText\n}","url":"https://tauri.studio/docs/api/js/modules/http#ResponseType"},{"id":"ts_http_Class_Body","name":"Body","kind":"Class","module":"http","language":"typescript","declaration":"Class Body {\n\tpayload,\n\ttype,\n\tbytes,\n\tform,\n\tjson,\n\ttext\n}","url":"https://tauri.studio/docs/api/js/classes/http.Body"},{"id":"ts_http_Class_Client","name":"Client","kind":"Class","module":"http","language":"typescript","declaration":"Class Client {\n\tid,\n\tdelete,\n\tdrop,\n\tget,\n\tpatch,\n\tpost,\n\tput,\n\trequest\n}","url":"https://tauri.studio/docs/api/js/classes/http.Client"},{"id":"ts_http_Class_Response","name":"Response","kind":"Class","module":"http","language":"typescript","declaration":"Class Response {\n\tdata,\n\theaders,\n\tok,\n\trawHeaders,\n\tstatus,\n\turl\n}","url":"https://tauri.studio/docs/api/js/classes/http.Response"},{"id":"ts_http_Interface_ClientOptions","name":"ClientOptions","kind":"Interface","module":"http","language":"typescript","declaration":"interface ClientOptions {\n\tconnectTimeout,\n\tmaxRedirections\n}","url":"https://tauri.studio/docs/api/js/modules/http#ClientOptions"},{"id":"ts_http_Interface_HttpOptions","name":"HttpOptions","kind":"Interface","module":"http","language":"typescript","declaration":"interface HttpOptions {\n\tbody,\n\theaders,\n\tmethod,\n\tquery,\n\tresponseType,\n\ttimeout,\n\turl\n}","url":"https://tauri.studio/docs/api/js/modules/http#HttpOptions"},{"id":"ts_http_Type_alias_FetchOptions","name":"FetchOptions","kind":"Type alias","module":"http","language":"typescript","type":{"type":"reference","typeArguments":[{"type":"reference","id":196,"name":"HttpOptions"},{"type":"literal","value":"url"}],"qualifiedName":"Omit","package":"typescript","name":"Omit"},"declaration":"Type alias FetchOptions","url":"https://tauri.studio/docs/api/js/modules/http#FetchOptions"},{"id":"ts_http_Type_alias_HttpVerb","name":"HttpVerb","kind":"Type alias","module":"http","language":"typescript","type":{"type":"union","types":[{"type":"literal","value":"GET"},{"type":"literal","value":"POST"},{"type":"literal","value":"PUT"},{"type":"literal","value":"DELETE"},{"type":"literal","value":"PATCH"},{"type":"literal","value":"HEAD"},{"type":"literal","value":"OPTIONS"},{"type":"literal","value":"CONNECT"},{"type":"literal","value":"TRACE"}]},"declaration":"Type alias HttpVerb","url":"https://tauri.studio/docs/api/js/modules/http#HttpVerb"},{"id":"ts_http_Type_alias_Part","name":"Part","kind":"Type alias","module":"http","language":"typescript","type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"reference","qualifiedName":"Uint8Array","package":"typescript","name":"Uint8Array"}]},"declaration":"Type alias Part","url":"https://tauri.studio/docs/api/js/modules/http#Part"},{"id":"ts_http_Type_alias_RequestOptions","name":"RequestOptions","kind":"Type alias","module":"http","language":"typescript","type":{"type":"reference","typeArguments":[{"type":"reference","id":196,"name":"HttpOptions"},{"type":"union","types":[{"type":"literal","value":"method"},{"type":"literal","value":"url"}]}],"qualifiedName":"Omit","package":"typescript","name":"Omit"},"declaration":"Type alias RequestOptions","url":"https://tauri.studio/docs/api/js/modules/http#RequestOptions"},{"id":"ts_http_Function_fetch","name":"fetch","kind":"Function","module":"http","language":"typescript","declaration":"function fetch(fetch: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/http#fetch"},{"id":"ts_http_Function_getClient","name":"getClient","kind":"Function","module":"http","language":"typescript","declaration":"function getClient(getClient: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/http#getClient"},{"id":"ts_notification_Namespace_notification","name":"notification","kind":"Namespace","module":"notification","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.notification` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n\nThe APIs must be allowlisted on `tauri.conf.json`:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"notification\": {\n \"all\": true // enable all notification APIs\n }\n }\n }\n}\n```\nIt is recommended to allowlist only the APIs you use for optimal bundle size and security.","declaration":"Module notification","url":"https://tauri.studio/docs/api/js/modules/notification#notification"},{"id":"ts_notification_Interface_Options","name":"Options","kind":"Interface","module":"notification","language":"typescript","declaration":"interface Options {\n\tbody,\n\ticon,\n\ttitle\n}","url":"https://tauri.studio/docs/api/js/modules/notification#Options"},{"id":"ts_notification_Type_alias_Permission","name":"Permission","kind":"Type alias","module":"notification","language":"typescript","type":{"type":"union","types":[{"type":"literal","value":"granted"},{"type":"literal","value":"denied"},{"type":"literal","value":"default"}]},"declaration":"Type alias Permission","url":"https://tauri.studio/docs/api/js/modules/notification#Permission"},{"id":"ts_notification_Function_isPermissionGranted","name":"isPermissionGranted","kind":"Function","module":"notification","language":"typescript","declaration":"function isPermissionGranted(isPermissionGranted: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/notification#isPermissionGranted"},{"id":"ts_notification_Function_requestPermission","name":"requestPermission","kind":"Function","module":"notification","language":"typescript","declaration":"function requestPermission(requestPermission: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/notification#requestPermission"},{"id":"ts_notification_Function_sendNotification","name":"sendNotification","kind":"Function","module":"notification","language":"typescript","declaration":"function sendNotification(sendNotification: void) { ... }","url":"https://tauri.studio/docs/api/js/modules/notification#sendNotification"},{"id":"ts_os_Namespace_os","name":"os","kind":"Namespace","module":"os","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.os` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n\nThe APIs must be allowlisted on `tauri.conf.json`:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"os\": {\n \"all\": true, // enable all Os APIs\n }\n }\n }\n}\n```\nIt is recommended to allowlist only the APIs you use for optimal bundle size and security.","declaration":"Module os","url":"https://tauri.studio/docs/api/js/modules/os#os"},{"id":"ts_os_Variable_EOL","name":"EOL","kind":"Variable","module":"os","language":"typescript","type":{"type":"union","types":[{"type":"literal","value":"\r\n"},{"type":"literal","value":"\n"}]},"declaration":"Variable EOL","url":"https://tauri.studio/docs/api/js/modules/os#EOL"},{"id":"ts_os_Function_arch","name":"arch","kind":"Function","module":"os","language":"typescript","declaration":"function arch(arch: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/os#arch"},{"id":"ts_os_Function_platform","name":"platform","kind":"Function","module":"os","language":"typescript","declaration":"function platform(platform: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/os#platform"},{"id":"ts_os_Function_tempdir","name":"tempdir","kind":"Function","module":"os","language":"typescript","declaration":"function tempdir(tempdir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/os#tempdir"},{"id":"ts_os_Function_type","name":"type","kind":"Function","module":"os","language":"typescript","declaration":"function type(type: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/os#type"},{"id":"ts_os_Function_version","name":"version","kind":"Function","module":"os","language":"typescript","declaration":"function version(version: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/os#version"},{"id":"ts_path_Namespace_path","name":"path","kind":"Namespace","module":"path","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.path` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n\nThe APIs must be allowlisted on `tauri.conf.json`:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"path\": {\n \"all\": true, // enable all Path APIs\n }\n }\n }\n}\n```\nIt is recommended to allowlist only the APIs you use for optimal bundle size and security.","declaration":"Module path","url":"https://tauri.studio/docs/api/js/modules/path#path"},{"id":"ts_path_Reference_BaseDirectory","name":"BaseDirectory","kind":"Reference","module":"path","language":"typescript","declaration":"type BaseDirectory = {\n\tundefined\n}","url":"https://tauri.studio/docs/api/js/modules/path#BaseDirectory"},{"id":"ts_path_Variable_delimiter","name":"delimiter","kind":"Variable","module":"path","language":"typescript","type":{"type":"union","types":[{"type":"literal","value":";"},{"type":"literal","value":":"}]},"declaration":"Variable delimiter","url":"https://tauri.studio/docs/api/js/modules/path#delimiter"},{"id":"ts_path_Variable_sep","name":"sep","kind":"Variable","module":"path","language":"typescript","type":{"type":"union","types":[{"type":"literal","value":"\\"},{"type":"literal","value":"/"}]},"declaration":"Variable sep","url":"https://tauri.studio/docs/api/js/modules/path#sep"},{"id":"ts_path_Function_appDir","name":"appDir","kind":"Function","module":"path","language":"typescript","declaration":"function appDir(appDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#appDir"},{"id":"ts_path_Function_audioDir","name":"audioDir","kind":"Function","module":"path","language":"typescript","declaration":"function audioDir(audioDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#audioDir"},{"id":"ts_path_Function_basename","name":"basename","kind":"Function","module":"path","language":"typescript","declaration":"function basename(basename: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#basename"},{"id":"ts_path_Function_cacheDir","name":"cacheDir","kind":"Function","module":"path","language":"typescript","declaration":"function cacheDir(cacheDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#cacheDir"},{"id":"ts_path_Function_configDir","name":"configDir","kind":"Function","module":"path","language":"typescript","declaration":"function configDir(configDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#configDir"},{"id":"ts_path_Function_dataDir","name":"dataDir","kind":"Function","module":"path","language":"typescript","declaration":"function dataDir(dataDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#dataDir"},{"id":"ts_path_Function_desktopDir","name":"desktopDir","kind":"Function","module":"path","language":"typescript","declaration":"function desktopDir(desktopDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#desktopDir"},{"id":"ts_path_Function_dirname","name":"dirname","kind":"Function","module":"path","language":"typescript","declaration":"function dirname(dirname: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#dirname"},{"id":"ts_path_Function_documentDir","name":"documentDir","kind":"Function","module":"path","language":"typescript","declaration":"function documentDir(documentDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#documentDir"},{"id":"ts_path_Function_downloadDir","name":"downloadDir","kind":"Function","module":"path","language":"typescript","declaration":"function downloadDir(downloadDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#downloadDir"},{"id":"ts_path_Function_executableDir","name":"executableDir","kind":"Function","module":"path","language":"typescript","declaration":"function executableDir(executableDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#executableDir"},{"id":"ts_path_Function_extname","name":"extname","kind":"Function","module":"path","language":"typescript","declaration":"function extname(extname: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#extname"},{"id":"ts_path_Function_fontDir","name":"fontDir","kind":"Function","module":"path","language":"typescript","declaration":"function fontDir(fontDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#fontDir"},{"id":"ts_path_Function_homeDir","name":"homeDir","kind":"Function","module":"path","language":"typescript","declaration":"function homeDir(homeDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#homeDir"},{"id":"ts_path_Function_isAbsolute","name":"isAbsolute","kind":"Function","module":"path","language":"typescript","declaration":"function isAbsolute(isAbsolute: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#isAbsolute"},{"id":"ts_path_Function_join","name":"join","kind":"Function","module":"path","language":"typescript","declaration":"function join(join: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#join"},{"id":"ts_path_Function_localDataDir","name":"localDataDir","kind":"Function","module":"path","language":"typescript","declaration":"function localDataDir(localDataDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#localDataDir"},{"id":"ts_path_Function_logDir","name":"logDir","kind":"Function","module":"path","language":"typescript","declaration":"function logDir(logDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#logDir"},{"id":"ts_path_Function_normalize","name":"normalize","kind":"Function","module":"path","language":"typescript","declaration":"function normalize(normalize: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#normalize"},{"id":"ts_path_Function_pictureDir","name":"pictureDir","kind":"Function","module":"path","language":"typescript","declaration":"function pictureDir(pictureDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#pictureDir"},{"id":"ts_path_Function_publicDir","name":"publicDir","kind":"Function","module":"path","language":"typescript","declaration":"function publicDir(publicDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#publicDir"},{"id":"ts_path_Function_resolve","name":"resolve","kind":"Function","module":"path","language":"typescript","declaration":"function resolve(resolve: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#resolve"},{"id":"ts_path_Function_resourceDir","name":"resourceDir","kind":"Function","module":"path","language":"typescript","declaration":"function resourceDir(resourceDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#resourceDir"},{"id":"ts_path_Function_runtimeDir","name":"runtimeDir","kind":"Function","module":"path","language":"typescript","declaration":"function runtimeDir(runtimeDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#runtimeDir"},{"id":"ts_path_Function_templateDir","name":"templateDir","kind":"Function","module":"path","language":"typescript","declaration":"function templateDir(templateDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#templateDir"},{"id":"ts_path_Function_videoDir","name":"videoDir","kind":"Function","module":"path","language":"typescript","declaration":"function videoDir(videoDir: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/path#videoDir"},{"id":"ts_process_Namespace_process","name":"process","kind":"Namespace","module":"process","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.process` when `tauri.conf.json > build > withGlobalTauri` is set to true.","declaration":"Module process","url":"https://tauri.studio/docs/api/js/modules/process#process"},{"id":"ts_process_Function_exit","name":"exit","kind":"Function","module":"process","language":"typescript","declaration":"function exit(exit: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/process#exit"},{"id":"ts_process_Function_relaunch","name":"relaunch","kind":"Function","module":"process","language":"typescript","declaration":"function relaunch(relaunch: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/process#relaunch"},{"id":"ts_shell_Namespace_shell","name":"shell","kind":"Namespace","module":"shell","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.shell` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n\nThe APIs must be allowlisted on `tauri.conf.json`:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"shell\": {\n \"all\": true, // enable all shell APIs\n \"execute\": true, // enable process spawn APIs\n \"sidecar\": true, // enable spawning sidecars\n \"open\": true // enable opening files/URLs using the default program\n }\n }\n }\n}\n```\nIt is recommended to allowlist only the APIs you use for optimal bundle size and security.\n\n## Security\n\nThis API has a scope configuration that forces you to restrict the programs and arguments that can be used.\n\n### Restricting access to the [[`open`]] API\n\nOn the allowlist, `open: true` means that the [[open]] API can be used with any URL,\nas the argument is validated with the `^https?://` regex.\nYou can change that regex by changing the boolean value to a string, e.g. `open: ^https://github.com/`.\n\n### Restricting access to the [[`Command`]] APIs\n\nThe `shell` allowlist object has a `scope` field that defines an array of CLIs that can be used.\nEach CLI is a configuration object `{ name: string, command: string, sidecar?: bool, args?: boolean | Arg[] }`.\n\n- `name`: the unique identifier of the command, passed to the [[Command.constructor | Command constructor]].\nIf it's a sidecar, this must be the value defined on `tauri.conf.json > tauri > bundle > externalBin`.\n- `command`: the program that is executed on this configuration. If it's a sidecar, it must be the same as `name`.\n- `sidecar`: whether the object configures a sidecar or a system program.\n- `args`: the arguments that can be passed to the program. By default no arguments are allowed.\n - `true` means that any argument list is allowed.\n - `false` means that no arguments are allowed.\n - otherwise an array can be configured. Each item is either a string representing the fixed argument value\n or a `{ validator: string }` that defines a regex validating the argument value.\n\n#### Example scope configuration\n\nCLI: `git commit -m \"the commit message\"`\n\nConfiguration:\n```json\n{\n \"scope\": {\n \"name\": \"run-git-commit\",\n \"command\": \"git\",\n \"args\": [\"commit\", \"-m\", { \"validator\": \"\\\\S+\" }]\n }\n}\n```\nUsage:\n```typescript\nimport { Command } from '@tauri-apps/api/shell'\nnew Command('run-git-commit', ['commit', '-m', 'the commit message'])\n```\n\nTrying to execute any API with a program not configured on the scope results in a promise rejection due to denied access.\n","declaration":"Module shell","url":"https://tauri.studio/docs/api/js/modules/shell#shell"},{"id":"ts_shell_Class_Child","name":"Child","kind":"Class","module":"shell","language":"typescript","declaration":"Class Child {\n\tconstructor,\n\tpid,\n\tkill,\n\twrite\n}","url":"https://tauri.studio/docs/api/js/classes/shell.Child"},{"id":"ts_shell_Class_Command","name":"Command","kind":"Class","module":"shell","language":"typescript","commentTags":[{"tag":"example","text":"\n```typescript\nconst command = new Command('node')\ncommand.on('close', data => {\n console.log(`command finished with code ${data.code} and signal ${data.signal}`)\n})\ncommand.on('error', error => console.error(`command error: \"${error}\"`))\ncommand.stdout.on('data', line => console.log(`command stdout: \"${line}\"`))\ncommand.stderr.on('data', line => console.log(`command stderr: \"${line}\"`))\n\nconst child = await command.spawn()\nconsole.log('pid:', child.pid)\n```\n"}],"declaration":"Class Command {\n\tconstructor,\n\tstderr,\n\tstdout,\n\texecute,\n\ton,\n\tspawn,\n\tsidecar\n}","url":"https://tauri.studio/docs/api/js/classes/shell.Command"},{"id":"ts_shell_Class_EventEmitter","name":"EventEmitter","kind":"Class","module":"shell","language":"typescript","declaration":"Class EventEmitter {\n\tconstructor,\n\ton\n}","url":"https://tauri.studio/docs/api/js/classes/shell.EventEmitter"},{"id":"ts_shell_Interface_ChildProcess","name":"ChildProcess","kind":"Interface","module":"shell","language":"typescript","declaration":"interface ChildProcess {\n\tcode,\n\tsignal,\n\tstderr,\n\tstdout\n}","url":"https://tauri.studio/docs/api/js/modules/shell#ChildProcess"},{"id":"ts_shell_Interface_SpawnOptions","name":"SpawnOptions","kind":"Interface","module":"shell","language":"typescript","declaration":"interface SpawnOptions {\n\tcwd,\n\tenv\n}","url":"https://tauri.studio/docs/api/js/modules/shell#SpawnOptions"},{"id":"ts_shell_Function_open","name":"open","kind":"Function","module":"shell","language":"typescript","declaration":"function open(open: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/shell#open"},{"id":"ts_tauri_Namespace_tauri","name":"tauri","kind":"Namespace","module":"tauri","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.tauri` when `tauri.conf.json > build > withGlobalTauri` is set to true.","declaration":"Module tauri","url":"https://tauri.studio/docs/api/js/modules/tauri#tauri"},{"id":"ts_tauri_Interface_InvokeArgs","name":"InvokeArgs","kind":"Interface","module":"tauri","language":"typescript","declaration":"interface InvokeArgs {\n\tundefined\n}","url":"https://tauri.studio/docs/api/js/modules/tauri#InvokeArgs"},{"id":"ts_tauri_Function_convertFileSrc","name":"convertFileSrc","kind":"Function","module":"tauri","language":"typescript","declaration":"function convertFileSrc(convertFileSrc: string) { ... }","url":"https://tauri.studio/docs/api/js/modules/tauri#convertFileSrc"},{"id":"ts_tauri_Function_invoke","name":"invoke","kind":"Function","module":"tauri","language":"typescript","declaration":"function invoke(invoke: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/tauri#invoke"},{"id":"ts_tauri_Function_transformCallback","name":"transformCallback","kind":"Function","module":"tauri","language":"typescript","declaration":"function transformCallback(transformCallback: number) { ... }","url":"https://tauri.studio/docs/api/js/modules/tauri#transformCallback"},{"id":"ts_updater_Namespace_updater","name":"updater","kind":"Namespace","module":"updater","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.updater` when `tauri.conf.json > build > withGlobalTauri` is set to true.","declaration":"Module updater","url":"https://tauri.studio/docs/api/js/modules/updater#updater"},{"id":"ts_updater_Interface_UpdateManifest","name":"UpdateManifest","kind":"Interface","module":"updater","language":"typescript","declaration":"interface UpdateManifest {\n\tbody,\n\tdate,\n\tversion\n}","url":"https://tauri.studio/docs/api/js/modules/updater#UpdateManifest"},{"id":"ts_updater_Interface_UpdateResult","name":"UpdateResult","kind":"Interface","module":"updater","language":"typescript","declaration":"interface UpdateResult {\n\tmanifest,\n\tshouldUpdate\n}","url":"https://tauri.studio/docs/api/js/modules/updater#UpdateResult"},{"id":"ts_updater_Interface_UpdateStatusResult","name":"UpdateStatusResult","kind":"Interface","module":"updater","language":"typescript","declaration":"interface UpdateStatusResult {\n\terror,\n\tstatus\n}","url":"https://tauri.studio/docs/api/js/modules/updater#UpdateStatusResult"},{"id":"ts_updater_Type_alias_UpdateStatus","name":"UpdateStatus","kind":"Type alias","module":"updater","language":"typescript","type":{"type":"union","types":[{"type":"literal","value":"PENDING"},{"type":"literal","value":"ERROR"},{"type":"literal","value":"DONE"},{"type":"literal","value":"UPTODATE"}]},"declaration":"Type alias UpdateStatus","url":"https://tauri.studio/docs/api/js/modules/updater#UpdateStatus"},{"id":"ts_updater_Function_checkUpdate","name":"checkUpdate","kind":"Function","module":"updater","language":"typescript","declaration":"function checkUpdate(checkUpdate: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/updater#checkUpdate"},{"id":"ts_updater_Function_installUpdate","name":"installUpdate","kind":"Function","module":"updater","language":"typescript","declaration":"function installUpdate(installUpdate: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/updater#installUpdate"},{"id":"ts_window_Namespace_window","name":"window","kind":"Namespace","module":"window","language":"typescript","comment":"This package is also accessible with `window.__TAURI__.window` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n\nThe APIs must be allowlisted on `tauri.conf.json`:\n```json\n{\n \"tauri\": {\n \"allowlist\": {\n \"window\": {\n \"all\": true, // enable all window APIs\n \"create\": true, // enable window creation\n \"center\": true,\n \"requestUserAttention\": true,\n \"setResizable\": true,\n \"setTitle\": true,\n \"maximize\": true,\n \"unmaximize\": true,\n \"minimize\": true,\n \"unminimize\": true,\n \"show\": true,\n \"hide\": true,\n \"close\": true,\n \"setDecorations\": true,\n \"setAlwaysOnTop\": true,\n \"setSize\": true,\n \"setMinSize\": true,\n \"setMaxSize\": true,\n \"setPosition\": true,\n \"setFullscreen\": true,\n \"setFocus\": true,\n \"setIcon\": true,\n \"setSkipTaskbar\": true,\n \"startDragging\": true,\n \"print\": true\n }\n }\n }\n}\n```\nIt is recommended to allowlist only the APIs you use for optimal bundle size and security.\n\n# Window events\n\nEvents can be listened using `appWindow.listen`:\n```typescript\nimport { appWindow } from '@tauri-apps/api/window'\nappWindow.listen('tauri://move', ({ event, payload }) => {\n const { x, y } = payload // payload here is a `PhysicalPosition`\n})\n```\n\nWindow-specific events emitted by the backend:\n\n#### 'tauri://resize'\nEmitted when the size of the window has changed.\n*EventPayload*:\n```typescript\ntype ResizePayload = PhysicalSize\n```\n\n#### 'tauri://move'\nEmitted when the position of the window has changed.\n*EventPayload*:\n```typescript\ntype MovePayload = PhysicalPosition\n```\n\n#### 'tauri://close-requested'\nEmitted when the user requests the window to be closed.\nIf a listener is registered for this event, Tauri won't close the window so you must call `appWindow.close()` manually.\n\n#### 'tauri://focus'\nEmitted when the window gains focus.\n\n#### 'tauri://blur'\nEmitted when the window loses focus.\n\n#### 'tauri://scale-change'\nEmitted when the window's scale factor has changed.\nThe following user actions can cause DPI changes:\n- Changing the display's resolution.\n- Changing the display's scale factor (e.g. in Control Panel on Windows).\n- Moving the window to a display with a different scale factor.\n*Event payload*:\n```typescript\ninterface ScaleFactorChanged {\n scaleFactor: number\n size: PhysicalSize\n}\n```\n\n#### 'tauri://menu'\nEmitted when a menu item is clicked.\n*EventPayload*:\n```typescript\ntype MenuClicked = string\n```\n","declaration":"Module window","url":"https://tauri.studio/docs/api/js/modules/window#window"},{"id":"ts_window_Enumeration_UserAttentionType","name":"UserAttentionType","kind":"Enumeration","module":"window","language":"typescript","declaration":"enum UserAttentionType {\n\tCritical,\n\tInformational\n}","url":"https://tauri.studio/docs/api/js/modules/window#UserAttentionType"},{"id":"ts_window_Class_LogicalPosition","name":"LogicalPosition","kind":"Class","module":"window","language":"typescript","declaration":"Class LogicalPosition {\n\tconstructor,\n\ttype,\n\tx,\n\ty\n}","url":"https://tauri.studio/docs/api/js/classes/window.LogicalPosition"},{"id":"ts_window_Class_LogicalSize","name":"LogicalSize","kind":"Class","module":"window","language":"typescript","declaration":"Class LogicalSize {\n\tconstructor,\n\theight,\n\ttype,\n\twidth\n}","url":"https://tauri.studio/docs/api/js/classes/window.LogicalSize"},{"id":"ts_window_Class_PhysicalPosition","name":"PhysicalPosition","kind":"Class","module":"window","language":"typescript","declaration":"Class PhysicalPosition {\n\tconstructor,\n\ttype,\n\tx,\n\ty,\n\ttoLogical\n}","url":"https://tauri.studio/docs/api/js/classes/window.PhysicalPosition"},{"id":"ts_window_Class_PhysicalSize","name":"PhysicalSize","kind":"Class","module":"window","language":"typescript","declaration":"Class PhysicalSize {\n\tconstructor,\n\theight,\n\ttype,\n\twidth,\n\ttoLogical\n}","url":"https://tauri.studio/docs/api/js/classes/window.PhysicalSize"},{"id":"ts_window_Class_WebviewWindow","name":"WebviewWindow","kind":"Class","module":"window","language":"typescript","commentTags":[{"tag":"example","text":"\n```typescript\n// loading embedded asset:\nconst webview = new WebviewWindow('theUniqueLabel', {\n url: 'path/to/page.html'\n})\n// alternatively, load a remote URL:\nconst webview = new WebviewWindow('theUniqueLabel', {\n url: 'https://github.com/tauri-apps/tauri'\n})\n\nwebview.once('tauri://created', function () {\n // webview window successfully created\n})\nwebview.once('tauri://error', function (e) {\n // an error happened creating the webview window\n})\n\n// emit an event to the backend\nawait webview.emit(\"some event\", \"data\")\n// listen to an event from the backend\nconst unlisten = await webview.listen(\"event name\", e => {})\nunlisten()\n```\n"}],"declaration":"Class WebviewWindow {\n\tconstructor,\n\tlabel,\n\tlisteners,\n\t_handleTauriEvent,\n\tcenter,\n\tclose,\n\temit,\n\thide,\n\tinnerPosition,\n\tinnerSize,\n\tisDecorated,\n\tisFullscreen,\n\tisMaximized,\n\tisResizable,\n\tisVisible,\n\tlisten,\n\tmaximize,\n\tminimize,\n\tonce,\n\touterPosition,\n\touterSize,\n\trequestUserAttention,\n\tscaleFactor,\n\tsetAlwaysOnTop,\n\tsetDecorations,\n\tsetFocus,\n\tsetFullscreen,\n\tsetIcon,\n\tsetMaxSize,\n\tsetMinSize,\n\tsetPosition,\n\tsetResizable,\n\tsetSize,\n\tsetSkipTaskbar,\n\tsetTitle,\n\tshow,\n\tstartDragging,\n\ttoggleMaximize,\n\tunmaximize,\n\tunminimize,\n\tgetByLabel\n}","url":"https://tauri.studio/docs/api/js/classes/window.WebviewWindow"},{"id":"ts_window_Class_WebviewWindowHandle","name":"WebviewWindowHandle","kind":"Class","module":"window","language":"typescript","declaration":"Class WebviewWindowHandle {\n\tconstructor,\n\tlabel,\n\tlisteners,\n\t_handleTauriEvent,\n\temit,\n\tlisten,\n\tonce\n}","url":"https://tauri.studio/docs/api/js/classes/window.WebviewWindowHandle"},{"id":"ts_window_Class_WindowManager","name":"WindowManager","kind":"Class","module":"window","language":"typescript","declaration":"Class WindowManager {\n\tconstructor,\n\tlabel,\n\tlisteners,\n\t_handleTauriEvent,\n\tcenter,\n\tclose,\n\temit,\n\thide,\n\tinnerPosition,\n\tinnerSize,\n\tisDecorated,\n\tisFullscreen,\n\tisMaximized,\n\tisResizable,\n\tisVisible,\n\tlisten,\n\tmaximize,\n\tminimize,\n\tonce,\n\touterPosition,\n\touterSize,\n\trequestUserAttention,\n\tscaleFactor,\n\tsetAlwaysOnTop,\n\tsetDecorations,\n\tsetFocus,\n\tsetFullscreen,\n\tsetIcon,\n\tsetMaxSize,\n\tsetMinSize,\n\tsetPosition,\n\tsetResizable,\n\tsetSize,\n\tsetSkipTaskbar,\n\tsetTitle,\n\tshow,\n\tstartDragging,\n\ttoggleMaximize,\n\tunmaximize,\n\tunminimize\n}","url":"https://tauri.studio/docs/api/js/classes/window.WindowManager"},{"id":"ts_window_Interface_Monitor","name":"Monitor","kind":"Interface","module":"window","language":"typescript","declaration":"interface Monitor {\n\tname,\n\tposition,\n\tscaleFactor,\n\tsize\n}","url":"https://tauri.studio/docs/api/js/modules/window#Monitor"},{"id":"ts_window_Interface_WindowOptions","name":"WindowOptions","kind":"Interface","module":"window","language":"typescript","declaration":"interface WindowOptions {\n\talwaysOnTop,\n\tcenter,\n\tdecorations,\n\tfileDropEnabled,\n\tfocus,\n\tfullscreen,\n\theight,\n\tmaxHeight,\n\tmaxWidth,\n\tmaximized,\n\tminHeight,\n\tminWidth,\n\tresizable,\n\tskipTaskbar,\n\ttitle,\n\ttransparent,\n\turl,\n\tvisible,\n\twidth,\n\tx,\n\ty\n}","url":"https://tauri.studio/docs/api/js/modules/window#WindowOptions"},{"id":"ts_window_Variable_appWindow","name":"appWindow","kind":"Variable","module":"window","language":"typescript","type":{"type":"reference","id":495,"name":"WebviewWindow"},"declaration":"Variable appWindow","url":"https://tauri.studio/docs/api/js/modules/window#appWindow"},{"id":"ts_window_Function_availableMonitors","name":"availableMonitors","kind":"Function","module":"window","language":"typescript","declaration":"function availableMonitors(availableMonitors: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/window#availableMonitors"},{"id":"ts_window_Function_currentMonitor","name":"currentMonitor","kind":"Function","module":"window","language":"typescript","declaration":"function currentMonitor(currentMonitor: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/window#currentMonitor"},{"id":"ts_window_Function_getAll","name":"getAll","kind":"Function","module":"window","language":"typescript","declaration":"function getAll(getAll: undefined) { ... }","url":"https://tauri.studio/docs/api/js/modules/window#getAll"},{"id":"ts_window_Function_getCurrent","name":"getCurrent","kind":"Function","module":"window","language":"typescript","declaration":"function getCurrent(getCurrent: WebviewWindow) { ... }","url":"https://tauri.studio/docs/api/js/modules/window#getCurrent"},{"id":"ts_window_Function_primaryMonitor","name":"primaryMonitor","kind":"Function","module":"window","language":"typescript","declaration":"function primaryMonitor(primaryMonitor: Promise) { ... }","url":"https://tauri.studio/docs/api/js/modules/window#primaryMonitor"}] \ No newline at end of file +[] \ No newline at end of file diff --git a/packages/tauri-search/src/generated/prose/tauri-docs_dev/documents.json b/packages/tauri-search/src/generated/prose/tauri-docs_dev/documents.json index 31a65fe..4ffce75 100644 --- a/packages/tauri-search/src/generated/prose/tauri-docs_dev/documents.json +++ b/packages/tauri-search/src/generated/prose/tauri-docs_dev/documents.json @@ -1 +1 @@ -[{"id":"prose_docs_architecture_md","title":"The Tauri Architecture","headings":["What does the Release flow look like"],"subHeadings":[],"code":[null],"text":"# The Tauri Architecture ## Introduction Tauri is a polyglot and generic toolkit\nthat is very composable and allows engineers to make a wide variety of\napplications. It is used for building applications for Desktop Computers using a\ncombination of Rust tools and HTML rendered in a Webview. Apps built with Tauri\ncan ship with any number of pieces of an optional JS API / Rust API so that\nwebviews can control the system via message passing. In fact, developers can\nextend the default API with their own functionality and bridge the Webview and\nRust-based backend easily. Tauri apps can have custom menus and have tray-type\ninterfaces. They can be updated, and are managed by the user's operating system\nas expected. They are very small, because they use the OS's webview. They do not\nship a runtime, since the final binary is compiled from Rust. This makes the\nreversing of Tauri apps not a trivial task. ## What Tauri is NOT - Tauri is not\na lightweight kernel wrapper...instead it directly uses [WRY](#wry) and\n[TAO](#tao) to do the heavy-lifting in making system calls to the OS. - Tauri is\nnot a VM or virtualized environment...instead it is an application toolkit that\nallows making Webview OS applications. ## Major Components The following section\nbriefly describes the roles of the various parts of Tauri. ### Tauri Core\n[STABLE RUST] ####\n[tauri](https://github.com/tauri-apps/tauri/tree/dev/core/tauri) This is the\nmajor crate that holds everything together. It brings the runtimes, macros,\nutilities and API into one final product. It reads the `tauri.conf.json` file at\ncompile time in order to bring in features and undertake actual configuration of\nthe app (and even the `Cargo.toml` file in the project's folder). It handles\nscript injection (for polyfills / prototype revision) at runtime, hosts the API\nfor systems interaction, and even manages updating. ####\n[tauri-build](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-build)\nApply the macros at build-time in order to rig some special features needed by\n`cargo`. ####\n[tauri-codegen](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-codegen)\n- Embed, hash, and compress assets, including icons for the app as well as the\nsystem-tray. - Parse `tauri.conf.json` at compile time and generate the Config\nstruct. ####\n[tauri-macros](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-macros)\nCreate macros for the context, handler, and commands by leveraging the\n`tauri-codegen` crate. ####\n[tauri-runtime](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime)\nThis is the glue layer between tauri itself and lower level webview libraries.\n####\n[tauri-runtime-wry](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime-wry)\nThis crate opens up direct systems-level interactions specifically for WRY, such\nas printing, monitor detection, and other windowing related tasks.\n`tauri-runtime` implementation for WRY. ####\n[tauri-utils](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-utils)\nThis is common code that is reused in many places and offers useful utilities\nlike parsing configuration files, detecting platform triples, injecting the CSP,\nand managing assets. ### Tauri Tooling ####\n[api](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) [TS -> JS] A\ntypescript library that creates `cjs` and `esm` Javascript endpoints for you to\nimport into your Frontend framework so that the Webview can call and listen to\nbackend activity. We also ship the pure typescript, because for some frameworks\nthis is more optimal. It uses the message passing of webviews to their hosts.\n#### [bundler](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler)\n[RUST / SHELL] The bundler is a library that builds a Tauri App for the platform\ntriple it detects / is told. At the moment it currently supports macOS, Windows\nand Linux - but in the near future will support mobile platforms as well. May be\nused outside of Tauri projects. ####\n[cli.js](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli.js) [JS]\nWritten in Typescript and packaged such that it can be used with `npm`, `pnpm`,\nand `yarn`, this library provides a node.js runner for common tasks when using\nTauri, like `yarn tauri dev`. For the most part it is a wrapper around\n[cli.rs](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli). ####\n[cli.rs](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) [RUST] This\nrust executable provides the full interface to all of the required activities\nfor which the CLI is required. It will run on macOS, Windows, and Linux. ####\n[create-tauri-app](https://github.com/tauri-apps/tauri/tree/dev/tooling/create-tauri-app)\n[JS] This is a toolkit that will enable engineering teams to rapidly scaffold\nout a new tauri-apps project using the frontend framework of their choice (as\nlong as it has been configured). # External Crates The Tauri-Apps organisation\nmaintains two \"upstream\" crates from Tauri, namely TAO for creating and managing\napplication windows, and WRY for interfacing with the Webview that lives within\nthe window. ## [TAO](https://github.com/tauri-apps/tao) Cross-platform\napplication window creation library in Rust that supports all major platforms\nlike Windows, macOS, Linux, iOS and Android. Written in Rust, it is a fork of\n[winit](https://github.com/rust-windowing/winit) that we have extended for our\nown needs like menu bar and system tray. ##\n[WRY](https://github.com/tauri-apps/wry) WRY is a cross-platform WebView\nrendering library in Rust that supports all major desktop platforms like\nWindows, macOS, and Linux. Tauri uses WRY as the abstract layer responsible to\ndetermine which webview is used (and how interactions are made). ##\n[tauri-hotkey-rs](https://github.com/tauri-apps/tauri-hotkey-rs) We needed to\nfix hotkey to work on all platforms, because upstream was not being responsive.\n# Additional tooling ##\n[binary-releases](https://github.com/tauri-apps/binary-releases) This is the\ndelivery mechanism for tauri prebuilt binaries: currently the cli.rs (used by\ncli.js) and rustup binaries (used by the deps install command of cli.js). These\nartifacts are automatically created on release. ##\n[tauri-action](https://github.com/tauri-apps/tauri-action) This is a github\nworkflow that builds tauri binaries for all platforms. It is not the fastest out\nthere, but it gets the job done and is highly configurable. Even allowing you to\ncreate a (very basic) tauri app even if tauri is not setup. ##\n[create-pull-request](https://github.com/tauri-apps/create-pull-request) Because\nthis is a very risky (potentially destructive) github action, we forked it in\norder to have strong guarantees that the code we think is running is actually\nthe code that is running. ##\n[vue-cli-plugin-tauri](https://github.com/tauri-apps/vue-cli-plugin-tauri) This\nplugin allows you to very quickly install tauri in a vue-cli project. ##\n[tauri-vscode](https://github.com/tauri-apps/tauri-vscode) This project enhances\nthe VS Code interface with several nice-to-have features. # Tauri Plugins\n[documentation](https://tauri.studio/en/docs/guides/plugin) Generally speaking,\nplugins are authored by third parties (even though there may be official,\nsupported plugins). A plugin generally does 3 things: 1. It provides rust code\nto do \"something\". 2. It provides interface glue to make it easy to integrate\ninto an app. 3. It provides a JS API for interfacing with the rust code. Here\nare several examples of Tauri Plugins: -\nhttps://github.com/tauri-apps/tauri-plugin-sql -\nhttps://github.com/tauri-apps/tauri-plugin-stronghold -\nhttps://github.com/tauri-apps/tauri-plugin-authenticator # Workflows ## What\ndoes the Development flow look like? A developer must first install the\nprerequisite toolchains for creating a Tauri app. At the very least this will\nentail installing rust & cargo, and most likely also a modern version of node.js\nand potentially another package manager. Some platforms may also require other\ntooling and libraries, but this has been documented carefully in the respective\nplatform docs. Because of the many ways to build front-ends, we will stick with\na common node.js based approach for development. (Note: Tauri does not by\ndefault ship a node.js runtime.) The easiest way to do this is to run the\nfollowing: ``` npx create-tauri-app ``` Which will ask you a bunch of questions\nabout the framework you want to install and then create everything you need in a\nsingle folder - some via the placement of template files and some through normal\ninstallation procedures of your framework. > If you don't use this process, you\nwill have to manually install the tauri cli, initialise tauri and manually\nconfigure the `tauri.conf.json` file. Once everything is installed, you can run:\n``` yarn tauri dev -or- npm run tauri dev ``` This will do several things: 1.\nstart the JS Framework devserver 2. begin the long process of downloading and\ncompiling the rust libraries 3. open an application window with devtools enabled\n4. keep a long-lived console alive If you change your HTML/CSS/TS/JS, your\nframework devserver should give you its best shot at instant hot module\nreloading and you will see the changes instantly. If you modify your rust code\nor anything in the Cargo.toml, the window will close while rust recompiles. When\nfinished it will reload. If you need to get deeper insight into your current\nproject, or triage requires investigation of installed components, just run: ```\nyarn tauri info ``` ## What does the Release flow look like? The release flow\nbegins with proper configuration in the `tauri.conf.json` file. In this file,\nthe developer can configure not only the basic behaviour of the application\n(like window size and decoration), they can also provide settings for signing\nand updating. Depending upon the operating system that the developer (or CI) is\nbuilding the application on, there will be an app built for them for that\nsystem. (Cross compilation is not currently available, however there is an\nofficial [GitHub Action](https://github.com/tauri-apps/tauri-action) that can be\nused to build for all platforms.) To kick off this process, just: ``` yarn tauri\nbuild ``` After some time, the process will end and you can see the results in\nthe `./src-tauri/target/release` folder. ## What does the End-User flow look\nlike? End users will be provided with binaries in ways that are appropriate for\ntheir systems. Whether macOS, Linux, or Windows, direct download or store\ninstallations - they will be able to follow procedures for installing and\nremoving that they are used to. ## What does the Updating flow look like? When a\nnew version is ready, the developer publishes the new signed artifacts to a\nserver (that they have configured within `tauri.conf.json`). The application can\npoll this server to see if there is a new release. When there is a new release,\nthe user is prompted to update. The application update is downloaded, verified\n(checksum & signature), updated, closed, and restarted. ## License Tauri itself\nis licensed under MIT or Apache-2.0. If you repackage it and modify any source\ncode, it is your responsibility to verify that you are complying with all\nupstream licenses. Tauri is provided AS-IS with no explicit claim for\nsuitability for any purpose. Here you may peruse our [Software Bill of\nMaterials](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri).","url":"https://tauri.studio/docs/architecture"},{"id":"prose_docs_faq_md","title":"Frequently Asked Questions","headings":[],"subHeadings":[],"code":[null],"text":"# error: could not find native static libraryWebView2LoaderStatic, perhaps an -L\nflag is missing? The WebView2 crate build pipeline requires `NuGet` to have a\n`PackageSource` to install the `Microsoft.Web.WebView2` package. If you never\nused `NuGet` before, you might need to create a file named `NuGet.Config` on\n`%APPDATA%/NuGet` folder, with the following contents: ``` ``` This\nconfiguration enables the default `NuGet` registry.","url":"https://tauri.studio/docs/faq"},{"id":"prose_docs_about_architecture_md","title":"The Tauri Architecture","area":"about","section":"about","headings":["What does the Release flow look like"],"subHeadings":[],"code":[null],"text":"# The Tauri Architecture ## Introduction Tauri is a polyglot and generic toolkit\nthat is very composable and allows engineers to make a wide variety of\napplications. It is used for building applications for Desktop Computers using a\ncombination of Rust tools and HTML rendered in a Webview. Apps built with Tauri\ncan ship with any number of pieces of an optional JS API / Rust API so that\nwebviews can control the system via message passing. In fact, developers can\nextend the default API with their own functionality and bridge the Webview and\nRust-based backend easily. Tauri apps can have custom menus and have tray-type\ninterfaces. They can be updated, and are managed by the user's operating system\nas expected. They are very small, because they use the OS's webview. They do not\nship a runtime, since the final binary is compiled from Rust. This makes the\nreversing of Tauri apps not a trivial task. ## What Tauri is NOT - Tauri is not\na lightweight kernel wrapper...instead it directly uses [WRY](#wry) and\n[TAO](#tao) to do the heavy-lifting in making system calls to the OS. - Tauri is\nnot a VM or virtualized environment...instead it is an application toolkit that\nallows making Webview OS applications. ## Major Components The following section\nbriefly describes the roles of the various parts of Tauri. ### Tauri Core\n[STABLE RUST] ####\n[tauri](https://github.com/tauri-apps/tauri/tree/dev/core/tauri) This is the\nmajor crate that holds everything together. It brings the runtimes, macros,\nutilities and API into one final product. It reads the `tauri.conf.json` file at\ncompile time in order to bring in features and undertake actual configuration of\nthe app (and even the `Cargo.toml` file in the project's folder). It handles\nscript injection (for polyfills / prototype revision) at runtime, hosts the API\nfor systems interaction, and even manages updating. ####\n[tauri-build](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-build)\nApply the macros at build-time in order to rig some special features needed by\n`cargo`. ####\n[tauri-codegen](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-codegen)\n- Embed, hash, and compress assets, including icons for the app as well as the\nsystem-tray. - Parse `tauri.conf.json` at compile time and generate the Config\nstruct. ####\n[tauri-macros](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-macros)\nCreate macros for the context, handler, and commands by leveraging the\n`tauri-codegen` crate. ####\n[tauri-runtime](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime)\nThis is the glue layer between tauri itself and lower level webview libraries.\n####\n[tauri-runtime-wry](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime-wry)\nThis crate opens up direct systems-level interactions specifically for WRY, such\nas printing, monitor detection, and other windowing related tasks.\n`tauri-runtime` implementation for WRY. ####\n[tauri-utils](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-utils)\nThis is common code that is reused in many places and offers useful utilities\nlike parsing configuration files, detecting platform triples, injecting the CSP,\nand managing assets. ### Tauri Tooling ####\n[api](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) [TS -> JS] A\ntypescript library that creates `cjs` and `esm` Javascript endpoints for you to\nimport into your Frontend framework so that the Webview can call and listen to\nbackend activity. We also ship the pure typescript, because for some frameworks\nthis is more optimal. It uses the message passing of webviews to their hosts.\n#### [bundler](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler)\n[RUST / SHELL] The bundler is a library that builds a Tauri App for the platform\ntriple it detects / is told. At the moment it currently supports macOS, Windows\nand Linux - but in the near future will support mobile platforms as well. May be\nused outside of Tauri projects. ####\n[cli.js](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli.js) [JS]\nWritten in Typescript and packaged such that it can be used with `npm`, `pnpm`,\nand `yarn`, this library provides a node.js runner for common tasks when using\nTauri, like `yarn tauri dev`. For the most part it is a wrapper around\n[cli.rs](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli). ####\n[cli.rs](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) [RUST] This\nrust executable provides the full interface to all of the required activities\nfor which the CLI is required. It will run on macOS, Windows, and Linux. ####\n[create-tauri-app](https://github.com/tauri-apps/tauri/tree/dev/tooling/create-tauri-app)\n[JS] This is a toolkit that will enable engineering teams to rapidly scaffold\nout a new tauri-apps project using the frontend framework of their choice (as\nlong as it has been configured). # External Crates The Tauri-Apps organisation\nmaintains two \"upstream\" crates from Tauri, namely TAO for creating and managing\napplication windows, and WRY for interfacing with the Webview that lives within\nthe window. ## [TAO](https://github.com/tauri-apps/tao) Cross-platform\napplication window creation library in Rust that supports all major platforms\nlike Windows, macOS, Linux, iOS and Android. Written in Rust, it is a fork of\n[winit](https://github.com/rust-windowing/winit) that we have extended for our\nown needs like menu bar and system tray. ##\n[WRY](https://github.com/tauri-apps/wry) WRY is a cross-platform WebView\nrendering library in Rust that supports all major desktop platforms like\nWindows, macOS, and Linux. Tauri uses WRY as the abstract layer responsible to\ndetermine which webview is used (and how interactions are made). ##\n[tauri-hotkey-rs](https://github.com/tauri-apps/tauri-hotkey-rs) We needed to\nfix hotkey to work on all platforms, because upstream was not being responsive.\n# Additional tooling ##\n[binary-releases](https://github.com/tauri-apps/binary-releases) This is the\ndelivery mechanism for tauri prebuilt binaries: currently the cli.rs (used by\ncli.js) and rustup binaries (used by the deps install command of cli.js). These\nartifacts are automatically created on release. ##\n[tauri-action](https://github.com/tauri-apps/tauri-action) This is a github\nworkflow that builds tauri binaries for all platforms. It is not the fastest out\nthere, but it gets the job done and is highly configurable. Even allowing you to\ncreate a (very basic) tauri app even if tauri is not setup. ##\n[create-pull-request](https://github.com/tauri-apps/create-pull-request) Because\nthis is a very risky (potentially destructive) github action, we forked it in\norder to have strong guarantees that the code we think is running is actually\nthe code that is running. ##\n[vue-cli-plugin-tauri](https://github.com/tauri-apps/vue-cli-plugin-tauri) This\nplugin allows you to very quickly install tauri in a vue-cli project. ##\n[tauri-vscode](https://github.com/tauri-apps/tauri-vscode) This project enhances\nthe VS Code interface with several nice-to-have features. # Tauri Plugins\n[documentation](https://tauri.studio/en/docs/guides/plugin) Generally speaking,\nplugins are authored by third parties (even though there may be official,\nsupported plugins). A plugin generally does 3 things: 1. It provides rust code\nto do \"something\". 2. It provides interface glue to make it easy to integrate\ninto an app. 3. It provides a JS API for interfacing with the rust code. Here\nare several examples of Tauri Plugins: -\nhttps://github.com/tauri-apps/tauri-plugin-sql -\nhttps://github.com/tauri-apps/tauri-plugin-stronghold -\nhttps://github.com/tauri-apps/tauri-plugin-authenticator # Workflows ## What\ndoes the Development flow look like? A developer must first install the\nprerequisite toolchains for creating a Tauri app. At the very least this will\nentail installing rust & cargo, and most likely also a modern version of node.js\nand potentially another package manager. Some platforms may also require other\ntooling and libraries, but this has been documented carefully in the respective\nplatform docs. Because of the many ways to build front-ends, we will stick with\na common node.js based approach for development. (Note: Tauri does not by\ndefault ship a node.js runtime.) The easiest way to do this is to run the\nfollowing: ``` npx create-tauri-app ``` Which will ask you a bunch of questions\nabout the framework you want to install and then create everything you need in a\nsingle folder - some via the placement of template files and some through normal\ninstallation procedures of your framework. > If you don't use this process, you\nwill have to manually install the tauri cli, initialise tauri and manually\nconfigure the `tauri.conf.json` file. Once everything is installed, you can run:\n``` yarn tauri dev -or- npm run tauri dev ``` This will do several things: 1.\nstart the JS Framework devserver 2. begin the long process of downloading and\ncompiling the rust libraries 3. open an application window with devtools enabled\n4. keep a long-lived console alive If you change your HTML/CSS/TS/JS, your\nframework devserver should give you its best shot at instant hot module\nreloading and you will see the changes instantly. If you modify your rust code\nor anything in the Cargo.toml, the window will close while rust recompiles. When\nfinished it will reload. If you need to get deeper insight into your current\nproject, or triage requires investigation of installed components, just run: ```\nyarn tauri info ``` ## What does the Release flow look like? The release flow\nbegins with proper configuration in the `tauri.conf.json` file. In this file,\nthe developer can configure not only the basic behaviour of the application\n(like window size and decoration), they can also provide settings for signing\nand updating. Depending upon the operating system that the developer (or CI) is\nbuilding the application on, there will be an app built for them for that\nsystem. (Cross compilation is not currently available, however there is an\nofficial [GitHub Action](https://github.com/tauri-apps/tauri-action) that can be\nused to build for all platforms.) To kick off this process, just: ``` yarn tauri\nbuild ``` After some time, the process will end and you can see the results in\nthe `./src-tauri/target/release` folder. ## What does the End-User flow look\nlike? End users will be provided with binaries in ways that are appropriate for\ntheir systems. Whether macOS, Linux, or Windows, direct download or store\ninstallations - they will be able to follow procedures for installing and\nremoving that they are used to. ## What does the Updating flow look like? When a\nnew version is ready, the developer publishes the new signed artifacts to a\nserver (that they have configured within `tauri.conf.json`). The application can\npoll this server to see if there is a new release. When there is a new release,\nthe user is prompted to update. The application update is downloaded, verified\n(checksum & signature), updated, closed, and restarted. ## License Tauri itself\nis licensed under MIT or Apache-2.0. If you repackage it and modify any source\ncode, it is your responsibility to verify that you are complying with all\nupstream licenses. Tauri is provided AS-IS with no explicit claim for\nsuitability for any purpose. Here you may peruse our [Software Bill of\nMaterials](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri).","url":"https://tauri.studio/docs/about/architecture"},{"id":"prose_docs_about_book_md","title":"Get the book","area":"about","section":"about","headings":["Outline","Errata"],"subHeadings":["tl","Introduction","About the Topic","What you will learn","Stuff you","Chapter 1 ","Chapter 2 ","Chapter 3 ","Chapter 4 ","Chapter 5 "],"code":[null],"text":"import useBaseUrl from '@docusaurus/useBaseUrl'\nTauri - From Theory to Practice [{useBaseUrl('img/bookCover.png')}]\nTauri: From Theory to Practice\nArchitecting Next-Gen Native-Apps for all Platforms [v1:Rust Edition]\nAuthors: [Daniel Thompson-Yvetot, Lucas Fernandes Gonçalves Nogueira]\nPublisher: TBD\nRelease: late 2020\n### tl;dr; Visit https://opencollective.com/tauri and preorder your copy of the\nbook today. Your donation will support the ongoing development of Tauri, and you\nwill receive advance digital PDF's for your review as chapters are completed.\nThe final book will ship concurrently with the release of 1.0.0 stable. If you\ndonate 10 USD / month to Tauri, you will get the advance PDF versions as soon as\nthey are released. If you just want to donate once: 15 USD for PDF and e-book,\n30 USD for print version and PDF, 40 USD for all three. All tutorial\nsubscription tiers receive the rolling PDF free of additional charge. ###\nIntroduction In 2020, the manufacture of native-apps has become easier and more\naccessible than ever before. All the same, beginners and seasoned developers\nalike are confronted with tough choices in a rapidly changing landscape of\nsecurity and privacy. This is especially true in the semi-trusted environment of\nuser devices. Tauri takes the guesswork out of the equation, as it was designed\nfrom the ground up to embrace new paradigms of secure development and creative\nflexibility that leverage the language features of Rust and lets you build an\napp using any frontend framework you like. Find out how you can design, build,\naudit and deploy tiny, fast, robust, and secure native applications for the\nmajor Desktop and Mobile platforms, all from the exact same codebase and in\nrecord time - without even needing to know the Rust programming language.\nAuthors Daniel and Lucas, the architects behind Tauri take you on a journey from\ntheory to execution, during which you will learn why Tauri was built and how it\nworks under the hood. Together with guest personalities that specialize in Open\nSource, DevOps, Security and Enterprise Architecture, this book also presents\ndiscourse-formatted philosophical discussions and open-source sustainability\nviewpoints from which your next-gen apps will profit - and your users will\nbenefit. In this book you will follow the authors in the iterative evolution of\na real project from conception to distribution - all with commentary, complete\ncode resources, built, and packaged Native Apps for reference and staged Capture\nthe Flag (CTF) challenges that progress in difficulty as your comprehension of\nthe system grows. ### About the Topic Tauri is a brand new way to make\ncross-platform native-apps for web, desktop and mobile. At this very moment, the\npre-alpha version of this MIT licensed community-based software is being\nprepared for public release: https://github.com/tauri-apps/tauri Tauri\nintroduces novel methods for WebView integration and innovative patterns for\nrobust threat evasion. The 1.0 release will ship with a multipurpose white-box\nanalyzer and decompiler for any kind of binary and an integrated CLI for\ningesting any type of HTML; which, when combined, provides developers and\nsecurity teams with a holistic platform that has never existed as a single unit\nbefore. Tauri bridges communities and opens up new opportunities for everyone\nfrom the front end developer all the way to the low-level security and network\nadministrators. Due to this level of complexity and robustness, it is important\nto publish a reference guide that will necessarily be updated as major versions\nare released. ### What you will learn By the end of this book you will\nunderstand: - The method and reasoning behind the design of Tauri - The options\nyou have when building with Tauri - That having a moral compass is possible in\nsoftware development - Why the Rust language makes the most sense as a binding\nand application layer - Why Electron, Cordova, React Native, Capacitor and\nothers are no longer the best choice - Why a binary review is important And you\nwill be able to: - Transform a simple website project into a Tauri Native-App -\nMake a variety of Tauri Application Types based on the main Patterns - Decompile\nand analyze your App for Security Issues - Publish your App to a variety of App\nStores - Read and write Rust code ### Stuff you'll get if you preorder - Access\nto a real demo App built for all platforms available at respective stores (that\nincludes CTF Flags). - Exclusive One-Pager cheat sheets made available for each\nsection of the book, including the Appendices. - Early access to videos /\nwebcasts. - Discounted participation in the “Capture the Flag” event hosted at\nthe launch of the book. ## Outline This is an early outline of the contents that\nwe expect to publish. Contents subject to change. ### Chapter 1 - Theory (ca. 50\npages - mostly conversational / technical, graphics) ``` 1. Security Starts with\nYou 2. Privacy Ends with ${you} 3. Languages, Dialects and Patterns 4.\nToolchains and Syntactic Sugar 5. Production Methodologies 6. Enterprise\nReadiness 7. Message Queueing 8. Embracing Chaos 9. Distribution Techniques 10.\nLicensing Strategies ``` ### Chapter 2 - Practice (ca. 130 pages w/ charts,\nscreenshots, code samples) ``` 1. Environment Prerequisites - Node, Npm, Yarn,\nRustc, Rustup, Buildtools 2. Development Platform Details - macOS - Windows -\nLinux - Docker - Virtual Machines - CI / CD 3. Tauri Introduction 4. Tauri\nAnatomy 5. Tauri Configuration - Files & Folders - Icons - Splash Screens -\nWindow - `src-tauri/tauri.conf.json` 6. Preparing your code - Transpile dynamic\nimports - Remove webpack chunking - Monolithic Files - Minification strategies\n7. Tauri API - Design Considerations - API Usage Patterns - Custom API Functions\n- Endpoints - All - Answer - Bridge - Event - Execute - List Files - Open - Read\nBinary File - Read Text File - Set Title - Window - Write File 8. Web APIs 9.\nTauri App Extensions - Anatomy - Flow - Registration - Publication - API 10.\nTaskbar Integration (Desktop Only) - Anatomy - Integrations - macOS - Windows -\nLinux 11. Security Features - Baseline Rust Features - Functional Address Space\nLayout Randomization (fASLR) - Ahead of Time (AoT) Compilation - Content\nSecurity Policy (CSP) - One Time Pads (OTP) - Embedded Server: False - API\nTree-Shaking - Matryoschkasumming (with Tauri-Frida) 12. Bridges and Brokers -\nBridge Patterns - Message hashing with OTP - Plugin Pattern - Kamikaze Function\nInjection (KFI) Closures 13. Testing - Unit Testing - Rust - JS - Integration\nTesting - e2e Testing 14. Building - Debugging - Packaging - Minification -\nDistribution Platform Details - macOS (.app / .dmg) - Win (.exe / .msi) - Linux\nArm64 (.appImage / .deb) - Linux x64 (.appImage / .deb) - iOS (.ipa) - Android\n(.apk) - PWA Website (with wasm) - Code Signing - Keystores - Certs -\nFingerprints - Providing License for End Users - Providers - Keys Files -\nSelf-Updater - Anatomy - Service Provisioning - Github - AWS - Homegrown -\nCross-Platform Bundler 15. Tauri-Frida Harness - Introduction to Reverse\nEngineering - Toolchain - Usage - Binary Hooking at Runtime - Pointer Evaluation\n- Spraying, Fuzzing, Spoofing - Report Generation - Recompilation - Post-Binary\nAnalysis 16. Distribution - Git - Mac Store - iOS Store - Play store - Windows\nStore - Snap Store - PureOS Store - .deb channels - .tar.gz - homebrew - Fdroid\n- Cydia - ChromeOS - WASM ``` ### Chapter 3 - Philosophical Discourses (ca. 40\npages of essays, some graphics) ``` 1. Rights and Responsibilities (with Robin\nvan Boven (SFOSC)) - Who You are Responsible To - Being a Vendor Comes with\nDuties - Ubiquitous Resources are Still Precious - Use Policy to Address\nResponsibilities - Take a Hippocratic Development Oath 2. Take a More Secure\nStance (with Liran Tal (SNYK)) - Security Benefits of Frameworks - Encrypt All\nthe Things, All the Time - Constantly Audit Project Dependencies - Harden\nYourself, Your Organization and Your Ecosystem - “Do What You Can Until You Run\nOut of Time.” - [ROBERT C. SEACORD] 3. Production Strategies for Sustainability\n(with Rhys Parry (Independent)) - Develop in the “Perfect” Environment - Minimal\nImpact for Existing Enterprise Architectures - Use Low-Barrier Tools for\nEnsuring Wholestack Security - Test the Right Things Intelligently - Post-Binary\nAnalysis and Redistribution - The Last Mile ``` ### Chapter 4 - Execution (ca.\n100 pages w/ code examples, screenshots, graphics) ``` 1. Base Pattern Evolution\n- Hermit - Bridge - Cloudish - Cloudbridge - Lockdown - Multiwin - GLUI 2.\nAdvanced Patterns - Cryptographic Enclave - Identity Management - Combine an App\nwith a Daemon - IPC / RPC - Integrate with DENO 3. UI Source Complilation -\nReact - Vue - Angular - Svelte - Gatsby 4. Building a Real App - Multiparty\nPassword Manager - Design - Prototyping - Testing - Debugging - Packaging -\nChecksumming 5. Tauri-Frida - White Box Reversing - Analyzing with Frida - Chaos\nExperiments - Interface Jacking - Disk Change - Latency - Process Kill - CPU\nThrottle - Static Analysis Reporting - Binary Repackaging - Inject License Keys\n- Clear Dead Codepoints - Recalculate Integrated Checksum 6. Publishing the App\n- Git - Mac Store - iOS Store - Play store - Windows Store - Snap Store - PureOS\nStore - .deb channels - .tar.gz - homebrew - Fdroid - Cydia - ChromeOS - WASM 7.\nPublishing an Update ``` ### Chapter 5 - Appendices (ca. 120 pages) ``` 1.\nConfiguration Options 2. Files and Repositories 3. Tauri CLI references 4. Tauri\nAPI references 5. ES6 References 6. Rust References 7. App Pattern Charts 8.\nTauri-Frida Reference 9. Glossary 10. Index ``` ## Errata Got something that you\nthink should be in the book? Want to be our publisher? Reach out to us and let\nus know!","url":"https://tauri.studio/docs/about/book"},{"id":"prose_docs_about_governance_md","title":"Governance","area":"about","section":"about","headings":["Sustainability"],"subHeadings":["Organizational Structure","Code of Conduct","Social Contract","Licensing","Trademark"],"code":[],"text":"## Sustainability One of the main goals of the organizational structure of Tauri\nis to guarantee the sustainability of Tauri and the health and well-being of its\ncontributors. The world of Open Source is fraught with peril and discord, and we\nhave taken measures to ensure the longevity of Tauri. This document explains how\nwe go about doing so. ### Organizational Structure Tauri apps is governed by the\ncommunity and work is done in the context of public working groups. Each working\ngroup has a dedicated channel on the Discord server as well as a Team on GitHub.\nOther than that, each WG is free to use whatever type of organizational model it\nchooses. The current working groups are: - WG Governance & Guidance - WG Tech -\nWG Education - WG Media - WG Security - WG Devops With the exception of the\nsecurity working group, which is by invite only and convenes privately, all\nother working groups are public and open to any and all participants. Please\nvisit [this repository](https://github.com/tauri-apps/governance-and-guidance)\nto get more information. ### Code of Conduct Everyone participating in the Tauri\ncommunity is expected to follow a code of conduct that you can at the\n[Governance and Guidance:Code of\nConduct](https://github.com/tauri-apps/governance-and-guidance/blob/master/CODE_OF_CONDUCT.md).\n### Social Contract We have a Social Contract that informs our decision making\nand organization. You can read about it here: [Governance and Guidance:Social\nContract](https://github.com/tauri-apps/governance-and-guidance/blob/master/SOCIAL_CONTRACT.md).\n### Licensing We, the contributors to Tauri Apps, use the MIT and Apache\nlicenses for all code content. Images and bodies of text, unless otherwise noted\nare CC-BY-ND-NC. ### Trademark It is a permissible use of the name \"Tauri App\"\nor the Tauri logo to show that a project uses Tauri. \"Tauri Studio\" is reserved\nfor use by the organization. Any language that gives the impression that the\nTauri organization approves, authorizes or otherwise supports a project, person\nor company is not permissible without written authorization from the Guidance\nand Governance Working Group.","url":"https://tauri.studio/docs/about/governance"},{"id":"prose_docs_about_intro_md","title":"What is Tauri?","area":"about","section":"about","headings":["Security First","Polyglots","Honest Open Source","The Future"],"subHeadings":[],"code":[],"text":"Tauri is a toolkit that helps developers make applications for the major desktop\nplatforms - using virtually any frontend framework in existence. The core is\nbuilt with Rust and the CLI leverages Node.js making Tauri a genuinely polyglot\napproach to creating and maintaining great apps. If you want to know more about\nthe technical details, then please visit the\n[Introduction](/docs/getting-started/beginning-tutorial). If you want to know\nmore about this project's philosophy - then keep reading.\n\n## Security First In today's world, every honest threat model assumes that the\nuser's device has already been compromised. This puts app developers in a\ncomplicated situation, because if the device is already at risk, how can the\nsoftware be trusted? Defense in depth is the approach we've taken. We want you\nto be able to take every precaution possible to minimise the surface area you\npresent to attackers. Tauri lets you choose which API endpoints to ship, whether\nor not you want a localhost server built into your app, and it even randomizes\nfunctional handles at runtime. These and other techniques form a secure baseline\nthat empowers you and your users. Slowing down attackers by making static\nattacks crushingly difficult and isolating systems from one another is the name\nof the game. And if you are coming from the Electron ecosystem - rest assured -\nby default Tauri only ships binaries, not ASAR files. By choosing to build Tauri\nwith security as a guiding force, we give you every opportunity to take a\nproactive security posture. ## Polyglots, not Silos Most contemporary frameworks\nuse a single language paradigm and are therefore trapped in a bubble of\nknowledge and idiom. This can work well for certain niche applications, but it\nalso fosters a kind of tribalism. This can be seen in the way that the React,\nAngular and Vue development communities huddle on their stacks, ultimately\nbreeding very little cross-pollination. This same situation can be seen in the\nRust vs Node vs C++ battlefields, where hardliners take their stances and refuse\nto collaborate across communities. Today, Tauri uses Rust for the backend - but\nin the not too distant future, other backends like Go, Nim, Python, Csharp etc.\nwill be possible. This is because we are maintaining the official Rust bindings\nto the [webview](https://github.com/webview) organisation and plan to let you\nswitch out the backend for your needs. Since our API can be implemented in any\nlanguage with C interop, full compliance is only a PR away. ## Honest Open\nSource None of this would make any sense without a community. Today software\ncommunities are amazing places where people help each other and make awesome\nthings - open source is a very big part of that. Open source means different\nthings to different people, but most will agree that it serves to support\nfreedom. When software doesn't respect your rights, then it can seem unfair and\npotentially compromise your freedoms by operating in unethical ways. This is why\nwe are proud that FLOSS advocates can build applications with Tauri that are\n\"certifiably\" open source and can be included in FSF endorsed GNU/Linux\ndistributions. ## The Future Tauri's future depends on your involvement and\ncontributions. Try it out, file issues, join a working group or make a donation\n- every contribution is important. Please, at any rate, do get in touch!!!","url":"https://tauri.studio/docs/about/intro"},{"id":"prose_docs_about_security_md","title":"Security","area":"about","section":"about","headings":["No Server Required","Language Features of Rust","Dynamic Ahead of Time Compilation ","Function Hardening","System Features","Ecosystem","Future Work"],"subHeadings":["Security Researchers","Functional ASLR","Kamikaze Function Injection","Bridge","One Time Pad Tokenization and Hashing","Allowing API","Content Security Policy Management","Decompilation is Difficult","Build Pipelines and Artifact Authenticity","Resilient PR and Approval Processes","Signed Binaries","Post","Post","Audits"],"code":[],"text":"This guide seeks to explain the high level concepts and Security Features at the\ncore of Tauri's design that make you, your apps and your users safer by default.\nPlease note:\nWhile we take every opportunity to help you harden your application - there are\nalways underlying threats like BIOS attacks, memory rowhammering and other\noperating system vulnerabilities that are constantly being discovered and (in\nthe best cases) responsibly disclosed.\nFurthermore, there are many ways that development teams can cut corners and\neither leak sensitive information or leave doors wide open to any of a range of\nattacks. Security is a never-ending quest, and your users count on you to keep\nthem safe.\nTherefore, we highly recommend that you take some time to consider the security\nramifications of everything that your application does, especially in the\ncontext of running on the semi-hostile platform of end-user devices.\nIf you need help or want a review, you are welcome to contact the Tauri team for\nsecurity consultation.\n### Security Researchers If you feel that there is a security concern or issue\nwith anything in Tauri, please do not publicly comment on your findings.\nInstead, reach out directly to our security team: > security@tauri.studio\nAlthough we do not currently have a budget for Security Bounties, in some cases\nwe will consider rewarding responsible disclosure with our limited resources. ##\nNo Server Required Tauri enables you to construct an application that uses\nweb-technology for the user interface without requiring you to use a server to\ncommunicate with the backend. Even if you used advanced techniques of dynamic\nimports and offload work to the backend, no traffic can be sniffed on TCP ports\nor external processes - because they just aren't there. This reduces not only\nthe physical and virtual footprint of your final binary by a good deal, it also\nreduces the surface area of potential attack vectors by removing them from the\nequation. ## Language Features of Rust By turning to the programming language\nrenowned for its memory-safety and speed, Tauri simply erases whole classes of\nconventional attacks. `Use after free` just isn't something that can happen with\nTauri. ## Dynamic Ahead of Time Compilation (AOT) This process of compilation\nhappens several times during the bootstrapping phase of a Tauri app. By using\nour default dynamic Ahead of Time compiler, you can generate code references\nthat are unique for every session and are still technically static code units.\n## Function Hardening ### Functional ASLR Functional address Space Layout\nRandomization techniques randomize function names at runtime and can implement\nOTP hashing so no two sessions are ever the same. We propose a novel type of\nfunction naming at boot time and optionally after every execution. Using a UID\nfor each function pointer prevents static attacks. ### Kamikaze Function\nInjection This advanced type of fASLR using the `EVENT` API endpoint, is a\npromise wrapped in a closure (with randomized handle) that Rust inserts at\nruntime into the WebView, where its interface is locked within the promise\nresolution handler and is nulled after execution. ### Bridge, don't serve\nInstead of passing potentially unsafe functions, an event bridge can be used to\npass messages and commands to named brokers at each respective side of the\napplication. ### One Time Pad Tokenization and Hashing Hashing important\nmessages with a OTP salt, you are able to encrypt messages between the user\ninterface and the Rust backend. We are currently investigating the use of\nadditional sources of entropy such as the amazing [Infinite Noise\nTRNG](https://13-37.org/en/shop/infinite-noise-trng/). ## System Features ###\nAllowing API You have the ability to pick and choose which API functions are\navailable to the UI and to Rust. If they are not enabled, the code will not be\nshipped with your app, which reduces binary size and attack surface. They are\nopt-in, so you have to consciously choose to progressively enhance your\napplication. ### Content Security Policy Management Preventing unauthorized code\nexecution for websites has long since been \"resolved\" by using CSPs. Tauri can\ninject CSPs into the index.html of the user interface, and when using a\nlocalhost server it will also send these headers to the UI or any other clients\nthat connect with it. ### Decompilation is Difficult This means that your apps\ncannot be easily decompiled as is the case with Electron ASAR files, which makes\nthe process of reverse engineering your project much more time intensive and\nrequires specialist training. ## Ecosystem ### Build Pipelines and Artifact\nAuthenticity The process of releasing our source-code artifacts is highly\nautomated, yet mandates kickoff and review from real humans. Our current release\nstrategy uses a combination of Github Actions and IOTA Tangle publication ###\nResilient PR and Approval Processes Our WG-TECH reviews code changes, tags PRs\nwith scope and make sure that everything stays up to date. And when its time to\npublish a new version, one of the maintainers tags a new release on master,\nwhich: - validates core - runs smoke tests - audits security for crates and npm\n- generates changelogs - creates artifacts - publishes checksums to IOTA -\ncreates a draft release Then the maintainer reviews the release notes, edits if\nnecessary - and a new release is forged. ## Future Work ### Signed Binaries\nBecause the entire project is shipped within a monolithic binary, code can be\nsigned for all distributables. (Currently using external tooling, but we are\nactively working on making the bundler a one-stop-shop.) This makes it virtually\nimpossible for hackers to change an installed Application without the operating\nsystem noticing. [Reference](https://github.com/electron/asar/issues/123) ###\nPost-Binary Analysis Use industrial-grade pentester-tooling (via our forthcoming\nTauri-Frida GUI) to discover and fix security weaknesses in your final binaries.\n### Post-Binary Enhancement After the build is before the delivery, and Tauri\nwill provide you with tools never seen before. Stay tuned! ### Audits We are\ncurrently in the process of our first external audit. When complete, we will\npublish the results here.","url":"https://tauri.studio/docs/about/security"},{"id":"prose_docs_architecture_build_tools_md","title":"Node Build Tools","area":"architecture","section":"architecture","headings":[],"subHeadings":[],"code":[],"text":"This is a stub. Could add notes about Vite, Webpack, Rollup, etc.","url":"https://tauri.studio/docs/architecture/build-tools"},{"id":"prose_docs_architecture_frontend_frameworks_md","title":"Frontend Frameworks","area":"architecture","section":"architecture","headings":[],"subHeadings":[],"code":[],"text":"This is a stub. Could add notes about Vite, Webpack, Rollup, etc.","url":"https://tauri.studio/docs/architecture/frontend-frameworks"},{"id":"prose_docs_architecture_patterns_about_patterns_md","title":"A word on patterns","area":"architecture","section":"patterns","headings":[],"subHeadings":[],"code":[],"text":"Tauri patterns are descriptions of use-cases that are entirely configurable\nwithin the `src-tauri/tauri.conf.json` file. These are not the limits of what\nTauri can do, and there are probably more out there. If you discover one, why\nnot get in touch and help us update this collection! If you haven't read about\nthe general design of Tauri, then it would make the most sense for you to visit\nthe [\"Getting Started\"](/docs/getting-started/beginning-tutorial) and become\nfamiliar with the basic architecture and terminology used in these patterns.","url":"https://tauri.studio/docs/architecture/patterns/about-patterns"},{"id":"prose_docs_architecture_patterns_bridge_md","title":"Bridge","area":"architecture","section":"patterns","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":[],"text":"import Rater from '@theme/Rater' import useBaseUrl from '@docusaurus/useBaseUrl'\n\nEase of Use Extensibility Performance Security\n\nBridge [{useBaseUrl('img/patterns/Bridge.svg')}]\nPros:\n * Highly configurable\n * No Rust skills required\n\nCons:\n * Some WebAPIs unavailable\n * Challenge to implement\n\n## Description The Bridge recipe is a secure pattern where messages are passed\nbetween brokers via an implicit bridge using the API. It isolates functionality\nto scope and passes messages instead of functionality. ## Diagram import\nMermaid, { colors } from '@theme/Mermaid' F subgraph WEBVIEW F-.-E end D-->E\nE-->D B-->D D-->B subgraph RUST A==>H A-->B B-.-C B-.-G end A[Binary] B{Rust\nBroker} C[Subprocess 2] G[Subprocess 1] D(( API BRIDGE )) E{JS Broker} F[Window]\nH{Bootstrap} style D fill:#ccc,stroke:#333,stroke-width:4px,color:white style\nRUST fill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px\nstyle WEBVIEW\nfill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`} /> ##\nConfiguration Here's what you need to add to your tauri.conf.json file: ```json\n\"tauri\": { \"allowlist\": { // all API values are default false \"all\": false, //\nuse this flag to enable all API features \"shell\": { \"execute\": false, // enable\napplication execution \"open\": false, // open link/path in the default app },\n\"fs\": { \"listFiles\": false, // list files in a directory \"readBinaryFile\":\nfalse, // read binary file from local filesystem \"readTextFile\": false, // read\ntext file from local filesystem \"setTitle\": false, // set the window title\n\"writeFile\": false // write file to local filesystem } } } ```","url":"https://tauri.studio/docs/architecture/patterns/bridge"},{"id":"prose_docs_architecture_patterns_cloudbridge_md","title":"Cloudbridge","area":"architecture","section":"patterns","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":[],"text":"import Rater from '@theme/Rater' import useBaseUrl from '@docusaurus/useBaseUrl'\n\nEase of Use Extensibility Performance Security\n\nCloudbridge [{useBaseUrl('img/patterns/Cloudbridge.svg')}]\nPros:\n * All available features\n * No Rust skills required\n\nCons:\n * Largest bundle size\n * Hard to separate concerns\n\n## Description The Cloudbridge recipe combines the flexibility of a localhost\nand the security of the bridge. With so many features, it can be easy to get\nlost. ## Diagram import Mermaid, { colors } from '@theme/Mermaid' F2 H==>D2\nD2-->F2 F2-->D2 B-->D D-->B E2-->D D-->E2 subgraph WEBVIEW F2 E2 end subgraph\nSERVER D2 E-->D2 end subgraph RUST A==>H A-->B B-.-C end A[Binary] B{Rust\nBroker} C[Subprocess] D(( API BRIDGE )) E{JS Broker} D2(( localhost )) E[bundled\nresources] E2{JS Broker} F2[Window] H{Bootstrap} style D\nfill:#ccc,stroke:#333,stroke-width:4px,color:white style RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px style\nWEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px\nstyle SERVER fill:#49A24A,stroke:#2B6063,stroke-width:4px `} /> ## Configuration\nHere's what you need to add to your tauri.conf.json file: ```json \"tauri\": {\n\"allowlist\": { \"all\": true // enable entire API } } ```","url":"https://tauri.studio/docs/architecture/patterns/cloudbridge"},{"id":"prose_docs_architecture_patterns_cloudish_md","title":"Cloudish","area":"architecture","section":"patterns","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":[],"text":"import Rater from '@theme/Rater' import useBaseUrl from '@docusaurus/useBaseUrl'\n\nEase of Use Extensibility Performance Security\n\nCloudish [{useBaseUrl('img/patterns/Cloudish.svg')}]\nPros:\n * Similar to a SPA web-app\n * No Rust skills required\n\nCons:\n * No access to Rust API\n * Uses a localhost server\n\n## Description The Cloudish recipe is a pattern for maximum flexibility and app\nperformance. It uses a localhost server, which means that your app will\ntechnically be available to other processes, like browsers and potentially other\ndevices on the network. All of your assets are baked into the binary, but served\nas if they were distinct files. ## Diagram import Mermaid, { colors } from\n'@theme/Mermaid' F H==>D D-->F F-->D subgraph RUST A==>H end subgraph WEBVIEW F\nend subgraph SERVER D E-->D end A[Binary] D(( localhost )) E[bundled resources]\nF[Window] H{Bootstrap} style RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px style\nWEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px\nstyle SERVER fill:#49A24A,stroke:#2B6063,stroke-width:4px`} /> ## Configuration\nHere's what you need to add to your tauri.conf.json file: ```json \"tauri\": {\n\"allowlist\": { \"all\": false // disable entire API } } ```","url":"https://tauri.studio/docs/architecture/patterns/cloudish"},{"id":"prose_docs_architecture_patterns_glui_md","title":"GLUI","area":"architecture","section":"patterns","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":[],"text":"import Alert from '@theme/Alert' import useBaseUrl from '@docusaurus/useBaseUrl'\nThis pattern is not available for now. import Rater from '@theme/Rater'\n\nEase of Use Extensibility Performance Security\n\nGLUI [{useBaseUrl('img/patterns/GLUI.svg')}]\nPros:\n * Framebuffer FTW\n * Window events rigged\n\nCons:\n * Broken on your machine\n\n## Description The GLUI is a research pattern that we will use internally to\ntest approaches using a GLUTIN window. We’re not sure yet if it will make the\nfinal cut as a bona fide alternative to WebView, although early tests with\ntransparent and multiwindow are exciting. ## Diagram import Mermaid, { colors }\nfrom '@theme/Mermaid' H H==>G A-->D D-->G subgraph GLUTIN G end subgraph RUST A\nend A[Binary] D(Framebuffer) G[GL Window] H{Bootstrap} style GLUTIN\nstroke:${colors.blue.dark},stroke-width:4px style RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px`} />\n## Configuration Here's what you need to add to your tauri.conf.json file:\n```json \"tauri\": { \"allowlist\": { // all API endpoints are default false \"all\":\nfalse, // disable the api }, \"window\": { // not yet normative \"glutin\": true,\n\"webview\": false } } ```","url":"https://tauri.studio/docs/architecture/patterns/glui"},{"id":"prose_docs_architecture_patterns_hermit_md","title":"Hermit","area":"architecture","section":"patterns","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":["json"],"text":"import Rater from '@theme/Rater' import useBaseUrl from '@docusaurus/useBaseUrl'\n\nEase of Use Extensibility Performance Security\n\nHermit [{useBaseUrl('img/patterns/Hermit.svg')}]\nPros:\n * Quick to make\n * Smallest size\n\nCons:\n * No remote resources\n * No access to API\n\n## Description The Hermit recipe is a pattern for ultimate application isolation\nwhere all logic is self-contained in the Window and the binary exists merely to\nbootstrap the Window. There is no communication back to Rust from the Window,\nthere is no localhost server, and the Window has no access to any remote\nresources. The Hermit is great for interactive Kiosk Mode and standalone HTML\nbased games. ## Diagram import Mermaid, { colors } from '@theme/Mermaid' H H==>F\nsubgraph WEBVIEW F end subgraph RUST A end A[fa:fa-cog Binary ]\nF[fa:fa-window-maximize Window] H{Bootstrap} style RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px style\nWEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`}\n/> ## Configuration Here's what you need to add to your tauri.conf.json file:\n```json \"tauri\": { \"allowlist\": { \"all\": false, // disable and tree-shake all\napi functions } } ```","url":"https://tauri.studio/docs/architecture/patterns/hermit"},{"id":"prose_docs_architecture_patterns_lockdown_md","title":"Lockdown","area":"architecture","section":"patterns","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":["json"],"text":"import Rater from '@theme/Rater' import useBaseUrl from '@docusaurus/useBaseUrl'\n\nEase of Use Extensibility Performance Security\n\nLockdown [{useBaseUrl('img/patterns/Lockdown.svg')}]\nPros:\n * Highest security rating\n * Elegant and powerful\n\nCons:\n * Rust skills required\n * No remote resources\n\n## Description The Lockdown recipe is a minimal usage of the [Bridge\npattern](/docs/architecture/patterns/bridge), which only allows interaction\nbetween Rust and the Window via expiring JS Promise Closures that are injected\ninto the Window by Rust and nulled as part of the callback. ## Diagram import\nMermaid, { colors } from '@theme/Mermaid' F G-.->B B-->G subgraph WEBVIEW G-->F\nend subgraph RUST A-->B A==>H end A[Binary] B[API:Event] F[Window] G((Promise\nClosure)) H{Bootstrap} style RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px style\nWEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`}\n/> ## Configuration Here's what you need to add to your tauri.conf.json file:\n```json \"tauri\": { \"allowlist\": {} // all API endpoints are default false } ```","url":"https://tauri.studio/docs/architecture/patterns/lockdown"},{"id":"prose_docs_architecture_patterns_multiwin_md","title":"Multiwin","area":"architecture","section":"patterns","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":[],"text":"import Alert from '@theme/Alert' import useBaseUrl from '@docusaurus/useBaseUrl'\nimport Rater from '@theme/Rater'\n\nEase of Use Extensibility Performance Security\n\nMultiwin [{useBaseUrl('img/patterns/Multiwin.svg')}]\nPros:\n * Windows can be spawned or destroyed at runtime\n * Separation of concerns\n\nCons:\n * Somewhat complex\n\n## Description The Multiwin recipe will allow you to have multiple windows. ##\nDiagram import Mermaid, { colors } from '@theme/Mermaid' H H==>F H==>G subgraph\nWEBVIEW F end subgraph WINIT G end subgraph RUST A end A[Binary] F[Window]\nG[Window] H{Bootstrap} style WINIT stroke:${colors.blue.dark},stroke-width:4px\nstyle RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px style\nWEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`}\n/> ## Configuration Here's what you need to add to your tauri.conf.json file:\n```json \"tauri\": { \"allowlist\": {}, // all API endpoints are default false\n\"windows\": [{ \"title\": \"Window1\", \"label\": \"main\", }, { \"title\": \"Splash\",\n\"label\": \"splashscreen\" }] } ```","url":"https://tauri.studio/docs/architecture/patterns/multiwin"},{"id":"prose_docs_building_anti_bloat_md","title":"Anti Bloat","area":"building","section":"building","headings":[],"subHeadings":["Rust Compression Features","Stripping","Allowlist config","UPX"],"code":[null,"json"],"text":"import Alert from '@theme/Alert' The following links have tutorials on reducing\nthe size of your installers: - https://github.com/RazrFalcon/cargo-bloat -\nhttps://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html -\nhttps://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections ###\nRust Compression Features Add this to your `src-tauri/Cargo.toml`\n[profile.release] panic = \"abort\" codegen-units = 1 lto = true incremental =\nfalse opt-level = \"s\" There is also `opt-level = \"z\"` available to try to reduce\nthe resulting binary size. `\"s\"` and `\"z\"` can sometimes be smaller than the\nother, so test it with your own application! We've seen smaller binary sizes\nfrom `\"s\"` for Tauri example applications, but real world applications can\nalways differ. #### Unstable Rust Compression Features The following suggestions\nare all unstable features and require a nightly toolchain. See the Unstable\nFeatures\n[https://doc.rust-lang.org/cargo/reference/unstable.html#unstable-features]\ndocumentation for more information of what this involves. The following methods\ninvolve using unstable compiler features and require having a rust nightly\ntoolchain installed. If you don't have the nightly toolchain + `rust-src`\nnightly component added, try the following: $ rustup toolchain install nightly $\nrustup component add rust-src --toolchain nightly The Rust Standard Library\ncomes precompiled. You can instead apply the optimization options used for the\nrest of your binary + dependencies to the std with an unstable flag. This flag\nrequires specifying your target, so know the target triple that you are\ntargeting. $ cargo +nightly build --release -Z build-std --target\nx86_64-unknown-linux-gnu If you are using `panic = \"abort\"` in your release\nprofile optimizations, then you need to make sure the `panic_abort` crate is\ncompiled with std. Additionally, an extra std feature can be used to further\nreduce the binary size. The following applies both: $ cargo +nightly build\n--release -Z build-std=std,panic_abort -Z\nbuild-std-features=panic_immediate_abort --target x86_64-unknown-linux-gnu See\nthe unstable documentation for more details about [`-Z\nbuild-std`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std)\nand [`-Z\nbuild-std-features`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std-features).\n### Stripping Binary size can easily be reduced by stripping out debugging\ninformation from binaries that ship to end users. This is not good for\ndebuggable builds, but means good binary size savings for end user binaries. The\neasiest way is to use the famous `strip` utility to remove this debugging\ninformation. $ strip target/release/my_application See your local `strip`\nmanpage for more information and flags that can be used to specify what\ninformation gets stripped out from the binary. ### Allowlist config You can also\nreduce the application size with the `allowlist` config, and only enabling what\nyou need. Sometimes this is useful with Tauri's\n[Bridge-Pattern](/docs/architecture/patterns/bridge) or others, depending on\nneeds. For example in `tauri.conf.json` file: ```json { \"tauri\": { \"allowlist\":\n{ \"all\": false, \"fs\": { \"writeFile\": true, \"writeBinaryFile\": true }, \"shell\": {\n\"execute\": true }, \"dialog\": { \"save\": true } } } } ``` ### UPX UPX, **Ultimate\nPacker for eXecutables**, is a dinosaur amongst the binary packers. This 23-year\nold, well-maintained piece of kit is GPL-v2 licensed with a pretty liberal usage\ndeclaration. Our understanding of the licensing is that you can use it for any\npurposes (commercial or otherwise) without needing to change your license unless\nyou modify the source code of UPX. Basically it compresses the binary and\ndecompresses it at runtime. It should work for pretty much any binary type out\nthere. Read more: https://github.com/upx/upx You should know that this technique\nmight flag your binary as a virus on Windows and macOS - so use at your own\ndiscretion, and as always validate with [Frida](https://frida.re/docs/home/) and\ndo real distribution testing! #### Usage on macOS $ brew install upx $ yarn\ntauri build $ upx --ultra-brute\nsrc-tauri/target/release/bundle/macos/app.app/Contents/macOS/app Ultimate Packer\nfor eXecutables Copyright (C) 1996 - 2018 UPX 3.95 Markus Oberhumer, Laszlo\nMolnar & John Reiser Aug 26th 2018 File size Ratio Format Name\n-------------------- ------ ----------- ----------- 963140 -> 274448 28.50%\nmacho/amd64 app","url":"https://tauri.studio/docs/building/anti-bloat"},{"id":"prose_docs_building_cross_platform_md","title":"Cross-Platform Compilation","area":"building","section":"building","headings":[],"subHeadings":[],"code":[],"text":"How to use GH Action for Building: a glance at Tauri Action.","url":"https://tauri.studio/docs/building/cross-platform"},{"id":"prose_docs_building_debian_md","title":"Debian packages","area":"building","section":"building","headings":[],"subHeadings":[],"code":["json"],"text":"import Alert from '@theme/Alert' Tauri allows your app to be packaged as a\n`.deb` (Debian package) file. # Bootstrapper Instead of launching the app\ndirectly, you can configure the bundled app to run a script that tries to expose\nthe environment variables to the app; without that you'll have trouble using\nsystem programs because the `PATH` environment variable isn't correct. Enable it\nwith the `useBootstrapper` [/docs/api/config#tauri.bundle.deb.useBootstrapper]\nconfig. # Custom files To include custom files to the debian package, you can\nconfigure a mapping on `tauri.conf.json > tauri > bundle > deb > files` as\nfollows: ```json { \"tauri\": { \"bundle\": { \"deb\": { \"files\": {\n\"/usr/lib/README.md\": \"../README.md\", // copies the README.md file to\n/usr/lib/README.md \"usr/lib/assets\": \"../public/\" // copies the entire public\ndirectory to /usr/lib/assets } } } } } ``` Each `files` object key is the path\non the debian package, and the value is a path to a file or directory relative\nto the `tauri.conf.json` file.","url":"https://tauri.studio/docs/building/debian"},{"id":"prose_docs_building_introduction_md","title":"Introduction","area":"building","section":"building","headings":[],"subHeadings":[],"code":[],"text":"The Tauri Bundler is a Rust harness for compiling your binary, packaging assets,\nand preparing a final bundle. It will detect your operating system and build a\nbundle accordingly. It currently supports: - Linux: .deb, .appimage - macOS:\n.app, .dmg - Windows: .exe, .msi","url":"https://tauri.studio/docs/building/introduction"},{"id":"prose_docs_building_sidecar_md","title":"Sidecar (Embedding External Binaries)","area":"building","section":"building","headings":["Running the sidecar binary on JavaScript","Running the sidecar binary on Rust","Using Node"],"subHeadings":[],"code":["json","bash","javascript","rust"],"text":"import Alert from '@theme/Alert' You may need to embed depending binaries in\norder to make your application work or to prevent users having to install\nadditional dependencies (e.g. Node.js, Python, etc). To bundle the binaries of\nyour choice, you can add the `externalBin` property to the `tauri > bundle`\nobject in your `tauri.conf.json`. See more about tauri.conf.json configuration\nhere [/docs/api/config#tauri.bundle]. `externalBin` expects a list of strings\ntargeting binaries either with absolute or relative paths. Here is a sample to\nillustrate the configuration, this is not a complete `tauri.conf.json` file:\n```json { \"tauri\": { \"bundle\": { \"externalBin\": [\"/absolute/path/to/app\",\n\"relative/path/to/binary\", \"bin/python\"] } } } ``` A binary with the same name\nand a `-$TARGET_TRIPLE` suffix must exist on the specified path. For instance,\n`\"externalBin\": [\"bin/python\"]` requires a\n`src-tauri/bin/python-x86_64-unknown-linux-gnu` executable on Linux. You can\nfind the current platform's target triple running the following command: ```bash\nrustc -Vv | grep host | cut -f2 -d' ' ``` Here's a Node.js script to append the\ntarget triple to a binary: ```javascript const execa = require('execa') const fs\n= require('fs') let extension = '' if (process.platform === 'win32') { extension\n= '.exe' } async function main() { const rustInfo = (await execa('rustc',\n['-vV'])).stdout const targetTriple = /host: (\\S+)/g.exec(rustInfo)[1] if\n(!targetTriple) { console.error('Failed to determine platform target triple') }\nfs.renameSync( `src-tauri/binaries/app${extension}`,\n`src-tauri/binaries/app-${targetTriple}${extension}` ) } main().catch((e) => {\nthrow e }) ``` ## Running the sidecar binary on JavaScript On the JavaScript\ncode, import the `Command` class on the `shell` module and use the `sidecar`\nstatic method: ```javascript import { Command } from '@tauri-apps/api/shell' //\nalternatively, use `window.__TAURI__.shell.Command` // `my-sidecar` is the value\nspecified on `tauri.conf.json > tauri > bundle > externalBin` const command =\nCommand.sidecar('my-sidecar') const output = await command.execute() ``` ##\nRunning the sidecar binary on Rust On the Rust code, import the `Command` struct\nfrom the `tauri::api::process` module: ```rust let (mut rx, mut child) =\nCommand::new_sidecar(\"my-sidecar\") .expect(\"failed to create `my-sidecar` binary\ncommand\") .spawn() .expect(\"Failed to spawn sidecar\");\ntauri::async_runtime::spawn(async move { // read events such as stdout while let\nSome(event) = rx.recv().await { if let CommandEvent::Stdout(line) = event {\nwindow .emit(\"message\", Some(format!(\"'{}'\", line))) .expect(\"failed to emit\nevent\"); // write to stdin child.write(\"message from\nRust\\n\".as_bytes()).unwrap(); } } }); ``` ## Using Node.js on a sidecar The\nTauri [sidecar\nexample](https://github.com/tauri-apps/tauri/tree/dev/examples/sidecar)\ndemonstrates how to use the sidecar API to run a Node.js application on Tauri.\nIt compiles the Node.js code using [pkg](https://github.com/vercel/pkg) and uses\nthe scripts above to run it.","url":"https://tauri.studio/docs/building/sidecar"},{"id":"prose_docs_community_ci_cd_md","title":"CI/CD","area":"community","section":"community","headings":["Continuous Integration","Continuous Deployment"],"subHeadings":["Introduction to immutable checksum","Next Steps"],"code":["yml"],"text":"## Continuous Integration Github Actions has two triggers of which we make heavy\nuse: `push` and `pull_request`. Every commit that made to the repo is a `push`.\nWhen you open a pull request from a branch (call it `great_feature`) to another\nbranch (our working branch, `dev`), each commit to `great_feature` would\npossibly trigger both of these events. We can use a filter to focus on the\nevents we care about though. In our workflows, we only PR (pull request) the\n`dev` and `master` branches. This means that if we filter to only the `dev` and\n`master` branches on commit, we will only run that workflow when we _merge_ a\nPR. A merged PR typically only occurs once a day or less so this will be a good\nfit for the longer running tests, e.g. the smoke tests in our case. Below is how\nthat might look. Unit tests: ```yml # these run fast so we can have them run on\nany commit name: unit tests on: pull_request: push: branches: - dev - master ```\nSmoke tests: ```yml # these run slower so we run only on merges to dev or master\nbranch name: smoke tests on: push: branches: - dev - master ``` Tauri operates\noff the `dev` branch as default, and merges to `master` for release. With these\nGithub Actions set up, we will run the unit tests on every commit to an open PR\n(see `pull_request`). When that PR is merged into `dev`, we will run both the\nunit tests and the smoke tests. ## Continuous Deployment ### Introduction to\nimmutable checksum It is not only possible, but trivial to modify release notes\nand artifacts after it has been published on Github. While there are very valid\nreasons for doing this, it is not exactly a totally trustworthy method - i.e.\nyou have no guarantee that what you are reading is really reflective of the\nunderlying truth or the tarballs. It is technically possible to change downloads\nover the wire or in the box or change checksums in targeted attacks. What we are\nseeking to accomplish is a best case scenario where: 1. Human error is reduced\nto a minimum, but humans are still integral in the actual release 2. Machine\nbuilt assets, changelogs and attached security audits are verifiable with\nchecksums that are published in an immutable, globally available store. To this\nend we fashioned a workflow shown below. As it stands now, we have #3 through #6\nimplemented. We manually do #2 which then feeds into #3 and kicks off the rest\nof the automatic workflow. 1. a human pushes to dev through a pull request (can\nhappen any number of times) - pull request includes a changeset file describing\nthe change and required version bump 2. a pull request is created (or updated)\nto include the change and version bump - this pull request stays open and will\nbe force pushed until it gets merged (and published) - increase the version\nnumber based on changesets - delete all changeset files 3. a codeowner merges\nthe publish PR to dev (no direct push permissible for anyone) - all tests (unit,\ne2e, smoke tests) are run on the PR - failures prevent the publish so they must\npass before merge 4. merge to dev triggers release sequence - changes are\nsquashed and a PR is opened against master 5. when PR to master is merged... -\nvulnerability audit (crates and yarn) and output saved - checksums and metadata\nand output saved - packages are published on npm/cargo, tarball/zip created -\nrelease is created for each package that had updates (if version isn't changed,\nbuild skips the publish steps) - output from audit/checksums is piped into the\nrelease body - tarball / zip attached to release - async process to publish to\nIOTA tangle (feeless) via release tag [note: still have things to resolve here]\n6. release is complete - master has updated code and tagged - GitHub release has\ntarballs, checksums, and changelog (may have multiple releases if more than one\npackage published) [note: is part of step 2 and is not yet implemented] ### Next\nSteps Next steps may include transferring and publishing the built assets to\nadditional places: 1. Tauri's private verdaccio 2. IPFS 3. PureOS Gitlab 4.\nGitHub Packages We can also do some interesting things like signing our\nreleases, including a hash in the release and/or even publishing this\ninformation on a blockchain that it can be easily verified. Publishing on the\nblockchain is another avenue to increase the confidence that what is seen on\nGitHub matches what you have downloaded. The IOTA foundation created a Github\nAction which will publish a release to their blockchain. This has shown promise,\nbut he gave a couple errors to tackle still.","url":"https://tauri.studio/docs/community/ci-cd"},{"id":"prose_docs_community_contributor_guide_md","title":"Contributor Guide","area":"community","section":"community","headings":["Contribution Flow","Hands On Example"],"subHeadings":["A Note About Contributions to the Rust Libraries"],"code":["sh","json","ini"],"text":"todo: make this friendlier and more complete Tauri is a polyglot system that\nuses: - git - Node.js - Rust - GitHub actions It can be developed on macOS,\nLinux and Windows. ## Contribution Flow 1. File an Issue 2. Fork the Repository\n3. Make Your Changes 4. Make a PR ### A Note About Contributions to the Rust\nLibraries When contributing to the Rust libraries `tauri`, `tauri-api`, and\n`tauri-updater`; you will want to setup an environment for RLS (the Rust\nLanguage Server). In the Tauri root directory, there is a `.scripts` folder that\ncontains a set of scripts to automate adding a couple temporary environment\nvariables to your shell/terminal. These environment variables point to\ndirectories in the test fixture which will prevent RLS from crashing on\ncompile-time. This is a necessary step for setting up a development environment\nfor Tauri's Rust libraries. ##### _Example Instructions_ 1. Navigate to the\nTauri Root directory. 2. Execute a script based on your Operating System from\nthis folder: `.scripts/init_env.bat` for Windows Cmd, `.scripts/init_env.ps1`\nfor Windows Powershell, `. .scripts/init_env.sh` for Linux/macOS bash (note the\nfirst `.` in this command). 3. Open your text editor/IDE from this\nshell/terminal. ## Hands On Example Let's make a new example. That's a great way\nto learn. We are going to assume you are on a nixy type of environment like\nLinux or macOS and have all of your development dependencies like rust and node\nalready sorted out. ```sh git clone git@github.com:tauri-apps/tauri.git cd\ntauri/cli/tauri.js yarn mkdir ../../examples/vanillajs && cd \"$_\" ``` ```json\n\"tauri:source\": \"node ../../../cli/tauri.js/bin/tauri\", ``` ```ini\n[dependencies.tauri] path = \"../../../../core/tauri\" features = [ \"all-api\" ]\n```","url":"https://tauri.studio/docs/community/contributor-guide"},{"id":"prose_docs_debugging_debugging_md","title":"Debugging","area":"debugging","section":"debugging","headings":["Rust Console","WebView JS Console","Create a Debug Build","Run Your App From the Terminal"],"subHeadings":[],"code":["rust","sh",null],"text":"import Alert from '@theme/Alert' import Command from '@theme/Command' With all\nthe moving pieces in Tauri, you may run into a problem that requires debugging.\nThere are a handful of locations where error details are printed, and Tauri\nincludes some tools to make the debugging process easier. ## Rust Console When\nyou run a Tauri app in development mode you will have a Rust console available.\nThis is in the terminal where you ran e.g. `tauri dev`. You can use the\nfollowing code to print something to that console from within a Rust file:\n```rust println!(\"Message from Rust: {}\", msg); ``` Sometimes you may have an\nerror in your Rust code, and the Rust compiler can give you lots of information.\nIf, for example, `tauri dev` crashes, you can rerun it like this on Linux and\nmacOS: ```sh RUST_DEBUG=1 tauri dev ``` or like this on MS Windows: ```sh set\nRUST_DEBUG=1 tauri dev ``` This will give you a granular stack trace. Generally\nspeaking, the Rust compiler will help you by giving you detailed information\nabout the issue, such as: ``` error[E0425]: cannot find value `sun` in this\nscope --> src/main.rs:11:5 | 11 | sun += i.to_string().parse::().unwrap(); | ^^^\nhelp: a local variable with a similar name exists: `sum` error: aborting due to\nprevious error For more information about this error, try `rustc --explain\nE0425`. ``` ## WebView JS Console Right click in the WebView, and choose\n`Inspect Element`. This will open up a web-inspector similar to the Chrome or\nFirefox dev tools you are used to. ## Create a Debug Build There are cases where\nyou might need to inspect the JS console in the final bundle, so Tauri provides\na simple command to create a debugging bundle: Like the normal build and dev\nprocesses, the first time you run this it will take more time than subsequent\nruns. The final bundled app will be placed in `src-tauri/target/debug/bundle`.\nThat app will ship with the development console enabled. ## Run Your App From\nthe Terminal You can also run a built app from the terminal, which will also\ngive you the Rust compiler notes (in case of errors) or your `println` messages.\nJust find the file `src-tauri/target/(release|debug)/[app name]` and either\ndouble click it (but be warned, the terminal will close on errors) or just run\nit in directly in your console.","url":"https://tauri.studio/docs/debugging/debugging"},{"id":"prose_docs_development_development_cycle_md","title":"Development Cycle","area":"development","section":"development","headings":[],"subHeadings":["1","2"],"code":[],"text":"import Alert from '@theme/Alert' import Command from '@theme/Command' ### 1.\nStart Your Devserver Now that you have everything setup, you should start your\napplication development server provided by your UI framework or bundler\n(assuming you're using one, of course). Every framework has its own development\ntooling. It is outside of the scope of this document to treat them all or keep\nthem up to date. ### 2. Start Tauri Development Window The first time you run\nthis command, it will take several minutes for the Rust package manager to\ndownload and build all the required packages. Since they are cached, subsequent\nbuilds will be much faster, as only your code will need rebuilding. Once Rust\nhas finished building, the webview will open and it should display your web app.\nYou can make changes to your web app, and if your tooling enables it, the\nwebview should update automatically just like a browser. When you make changes\nto your Rust files, they will be rebuilt automatically and your app will\nrestart. In your project repository, you SHOULD commit the\n\"src-tauri/Cargo.lock\" along with the \"src-tauri/Cargo.toml\" to git because\nCargo uses the lockfile to provide deterministic builds. As a result, it is\nrecommended that all applications check in their Cargo.lock. You SHOULD NOT\ncommit the \"src-tauri/target\" folder or any of its contents.","url":"https://tauri.studio/docs/development/development-cycle"},{"id":"prose_docs_development_security_md","title":"Security","area":"development","section":"development","headings":["Tauri Features to keep you Safer"],"subHeadings":["Secure content loading","Isolation pattern","Tauri API"],"code":["typescript","rust","json"],"text":"import Alert from '@theme/Alert' Whether you like it or not, today's\napplications live in operating systems that can be -- and regularly are --\ncompromised by any number of attacks. When your insecure application is a\ngateway for such lateral movement into the operating system, you are\ncontributing to the tools that professional hackers have at their disposal.\nDon't be a tool. This is why we have taken every opportunity to help you secure\nyour application, prevent undesired access to system level interfaces, and\nmanufacture bullet-proof applications. Your users assume you are following best\npractices. We make that easy, but you should still read up on it below. ##\nSecurity Is A Community Responsibility (adapted from\n[Electron](https://www.electronjs.org/docs/latest/tutorial/security#security-is-everyones-responsibility))\nIt is important to remember that the security of your Tauri application is the\nresult of the overall security of Tauri itself, all Rust and NPM dependencies,\nyour code, and the devices that run the final application. The Tauri Team does\nits best to do its part, the security community does its part, and you too would\ndo well to follow a few important best practices: - **Keep your application\nup-to-date with the latest Tauri release.** When releasing your app into the\nwild, you are also shipping a bundle that has Tauri in it. Vulnerabilities\naffecting Tauri may impact the security of your application. By updating Tauri\nto the latest version, you ensure that critical vulnerabilities are already\npatched and cannot be exploited in your application. Also be sure to keep your\ncompiler (rustc) and transpilers (nodejs) up to date, because there are often\nsecurity issues that are resolved. - **Evaluate your dependencies.** While NPM\nand Crates.io provide many convenient packages, it is your responsibility to\nchoose trustworthy 3rd-party libraries - or rewrite them in Rust. If you do use\noutdated libraries affected by known vulnerabilities or are unmaintained, your\napplication security and good-night's sleep could be in jeopardy. Use tooling\nlike `npm audit` and `cargo audit` to automate this process and lean on the\nsecurity community's important work. - **Adopt more secure coding practices.**\nThe first line of defense for your application is your own code. Although Tauri\ncan protect you from common web vulnerabilities, such as Cross-Site Scripting\nbased Remote Code Execution, improper configurations can have a security impact.\nEven if this were not the case, it is highly recommended to adopt secure\nsoftware development best practices and perform security testing. We detail what\nthis means in the next section. - **Educate your Users.** True security really\nmeans that unexpected behaviour cannot happen. So in a sense, being more secure\nmeans having the peace of mind in knowing that ONLY those things that you want\nto happen can happen. In the real world, though, this is a utopian \"dream\".\nHowever, by removing as many vectors as possible and building on a solid\nfoundation, your choice for Tauri is a signal to your users that you really care\nabout them, their safety, and their devices. ## Threat Models Tauri applications\nare composed of many pieces at different points of the lifecycle. Here we\ndescribe classical threats and what you SHOULD do about them. - **Upstream\nThreats.** Tauri is a direct dependency of your project, and we maintain strict\nauthorial control of commits, reviews, pull-requests, and releases. We do our\nbest to maintain up-to-date dependencies and take action to either update or\nfork&fix. Other projects may not be so well maintained, and may not even have\never been audited. Please consider their health when integrating them, because\notherwise you may have adopted architectural debt without even knowing it. -\n**Development Threats.** We assume that you, the developer, care for your\ndevelopment environment like a shrine of purity because it is a thing of beauty.\nIt is on you to make sure that your operating system, build toolchains, and\nassociated dependencies are kept up to date. A very real risk all of us face is\nwhat is known as \"supply-chain attacks\", which are usually considered to be\nattacks on direct dependencies of your project. However, there is a growing\nclass of attacks in the wild that directly target development machines, and you\nwould be well-off to address these head-on. One practice that we highly\nrecommend, even if it is a bit more time intensive, is to only ever consume\ncritical dependencies from git using hash revisions at best or named tags as\nsecond best. This holds true for Rust as well as the Node ecosystem. Also,\nconsider requiring all contributors to sign their commits and protect GIT\nbranches and pipelines. - **Buildtime Threats.** Modern organisations use CI/CD\nto manufacture binary artifacts. At Tauri, we even provide a Github Workflow for\nbuilding on multiple platforms. If you create your own CI/CD and depend on\nthird-party tooling, be wary of actions whose versions you have not explicitly\npinned. You should sign your binaries for the platform you are shipping to, and\nwhile this can be complicated and somewhat costly to setup, end-users expect\nthat your app is verifiably from you. - **Runtime Threats** We assume the\nwebview is insecure, which has led Tauri to implement several protections\nregarding webview access to system APIs in the context of loading untrusted\nuserland content. You can read more in detail below, but using the CSP will\nlockdown types of communication that the Webview can undertake. Furthermore,\nthere is a novel \"Isolation\" pattern that prevents untrusted content or scripts\nfrom accessing the API within the Webview. And please, whatever you do, DO NOT\ntrust the results of cryptography using private keys in the Webview. We gave you\nRust for a reason. - **Updater Threats** We have done our best to make shipping\nhot-updates to the app as straightforward and secure as possible. However, if\nyou lose control of the manifest server, the build server, or the binary hosting\nservice - all bets are off. If you are building your own system, consult a\nprofessional OPS architect and build it properly. ## An unsorted list of big ole\nDONT'S: - DON'T accept content over http:// or ws:// - DON'T ship an app with\nthe development console enabled - DON'T forget to [read about\nXSS](https://owasp.org/www-community/attacks/xss/) - DON'T ship any kind of\nlocalhost server unless the app needs to talk to other devices - DON'T consume\nJS from a CDN without using an integrity checksum ## Security Researchers\nNothing is perfect, attack vectors will be found, and if you have found one - we\nwant to know about it. If you have a discovery, PLEASE DO NOT FILE A PUBLIC\nISSUE OR MAKE A PULL REQUEST. Please discretely reach out to a member of the\nteam via Discord or Email for verification, vulnerability acceptance, and\nremediation timeline. We believe in - and participate in - responsible\ndisclosure. At this time we do not have a bug-bounty programme in place, but are\nactively considering it. ## Tauri Features to keep you Safer ### Secure content\nloading Tauri restricts the [Content Security Policy\n(CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) of your HTML\npages. Local scripts are hashed, styles and external scripts are referenced\nusing a cryptographic nonce, which prevents unallowed content from being loaded.\nThe CSP protection is only enabled if\n[`tauri.security.csp`](/docs/api/config/#tauri.security.csp) is set on the Tauri\nconfiguration file. You should make it as restricted as possible, only allowing\nthe webview to load assets from hosts you trust and preferably own. At compile\ntime, Tauri appends its nonces and hashes to the relevant CSP attributes\nautomatically, so you only need to worry about what is unique to your\napplication. See script-src\n[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src],\nstyle-src\n[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src]\nand CSP Sources\n[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources]\nfor more information about this protection. With the CSP protection enabled,\nusing inline `style` attributes it not allowed. Avoid loading remote content\nsuch as scripts served over a CDN as they introduce an attack vector, but any\nuntrusted file can introduce new and subtle attack vectors. ### Isolation\npattern To enable the isolation pattern, set\n[`tauri.pattern.use`](/docs/api/config/#tauri.pattern.use) to `isolation` and\ndefine the\n[`tauri.pattern.options.dir`](/docs/api/config/#tauri.pattern.options.dir)\nconfiguration to the path to the folder containing the `index.html` to be used\non the isolation iframe. Documentation details about the isolation pattern will\nbe updated soon. ### Tauri API The [Tauri\nAPI](https://www.npmjs.com/package/@tauri-apps/api) provides functions to access\ncommon native functionality such as filesystem access, HTTP requests, system\nnotifications and child processes usage. They provide an easy path to JavaScript\ndevelopers to access the operating system, but they should be used carefully.\n#### Prefer specific commands When accessing a native API, you should prefer\nwriting a dedicated command to implement your business logic instead of writing\neverything on the frontend layer. For instance, see the following frontend API\nusage: ```typescript import { writeFile, Dir } from '@tauri-apps/api/fs' await\nwriteFile({ path: 'report.txt', contents: 'the file content' }, { dir: Dir.App,\n}) ``` If you do not enable the [isolation pattern](#Isolation-pattern), an\nattacker with remote code execution can overwrite the contents of `report.txt`\nsince that API is generic and enabled. If you use a dedicated command, this is\nnot an issue: ```rust #[tauri::command] async fn write_report(app:\ntauri::AppHandle) -> Result<(), String> { let app_dir =\napp.path_resolver().app_dir().expect(\"failed to get app dir\"); let report_path =\napp_dir.join(\"report.txt\"); std::fs::write(&report_path, \"the file content\")\n.map_err(|e| e.to_string()); Ok(()) } fn main() { tauri::Builder::default()\n.invoke_handler(tauri::generate_handler![write_report])\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ```typescript import { invoke } from\n'@tauri-apps/api/tauri' await invoke('write_report') ``` This example command\nwritten on the backend cannot be exploited. Tauri recommends using the webview\nas only a user interface layer, keeping important logic on the core layer. ####\nThe allowlist When using the API package, you **must** enable only the\ninterfaces your application is using. See [the allowlist\nconfiguration](/docs/api/config/#tauri.allowlist) for options to restrict which\nAPIs are enabled. This not only reduces surface area, but also treeshakes out\nunneeded functionality -- which reduces final binary size. #### API scoping Some\nAPI modules provides a configuration to scope the API access and restrict the\nsystem resources accessed. ##### Filesystem You can restrict the folders and\nfiles that can be accessed when using the `fs` module. The scope array lists\nwhat paths are allowed using glob patterns and predefined variables that\nresolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`,\n`$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`,\n`$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`,\n`$RESOURCE`, `$APP` and `$CWD`. ```json { \"tauri\": { \"allowlist\": { \"fs\": {\n\"scope\": [\"$APP/db/*\", \"$RESOURCE/check.png\"] } } } } ``` ###### Asset protocol\nYou can restrict the folders and files that can be accessed when using the\n`asset` protocol. The scope array has the same syntax as the `fs` scope array:\n```json { \"tauri\": { \"allowlist\": { \"path\": { \"all\": true }, \"protocol\": {\n\"asset\": true, \"assetScope\": ['$APP/assets/*'] } } } } ``` ```typescript import\n{ appDir, join } from '@tauri-apps/api/path' import { convertFileSrc } from\n'@tauri-apps/api/tauri' const appDirPath = await appDir() // this path is\nallowed - is matches $APP/assets/* // you can use this on tags or window.fetch()\ncalls const allowedPath = convertFileSrc(await join(appDirPath, 'assets',\n'tauri.mp4')) // this path is not allowed - it does not match $APP/assets/*\nconst disallowedPath = convertFileSrc(await join(appDirPath, 'tauri.mp4')) ```\n###### HTTP You can restrict the URLs and paths that can be accessed when using\nthe `http` module: ```json { \"tauri\": { \"allowlist\": { \"http\": { \"scope\":\n[\"https://api.github.com/repos/tauri-apps/*\"] } } } } ``` ```typescript import {\nfetch } from '@tauri-apps/api/http' // this promise is resolved await\nfetch('https://api.github.com/repos/tauri-apps/tauri') // this promise is\nrejected - the URL is not allowed on the scope await\nfetch('https://api.github.com/repos/electron/electron') ``` ###### Shell To\nprevent unrestricted access to process spawning, Tauri offers a configuration to\ndefine programs and command line arguments that are allowed to be used. While it\ncan make userland ergonomics less simple, is good security hygiene to lock down\nshell commands from spawning other, unexpected commands. ```json { \"tauri\": {\n\"allowlist\": { \"shell\": { \"scope\": [ { \"name\": \"install-dep\", \"cmd\": \"apt-get\",\n\"args\": [ \"install\", { \"validator\": \"(gcc|rustc)$\" } ] } ], // allows using the\n`open` API only using arguments that match this regex // `true` is also a valid\nvalue, which defines the regex as `https?://`. \"open\":\n\"^https://github.com/tauri-apps/\" } } } } ``` ```typescript import { Command,\nopen } from '@tauri-apps/api/shell' // this command is allowed new\nCommand('install-dep', ['install', 'rustc']).spawn() // this command is not\nfound - does not match the `name` value of the scope definition new\nCommand('install-my-dep', ['install', 'rustc']).spawn() // this command is\nrejected - does not match validator regex for the second argument new\nCommand('install-dep', ['install', 'tar']).spawn() // this command is rejected -\nextra argument new Command('install-dep', ['install', 'rustc', '-y']).spawn() //\nthis open() usage is allowed because it matches the `open` regex await\nopen('https://github.com/tauri-apps/tauri') // this open() call is rejected -\ndoes not match validator regex open('https://docs.rs/tauri/latest/tauri') ```","url":"https://tauri.studio/docs/development/security"},{"id":"prose_docs_development_updating_dependencies_md","title":"Updating Dependencies","area":"development","section":"development","headings":["Automatic updates","Manual updates"],"subHeadings":["Update NPM Packages"],"code":[],"text":"import Alert from '@theme/Alert' Especially during the alpha and beta phases,\nyou are expected to keep all Tauri dependencies and toolchains up to date. There\nis no support for any versions other than latest. ## Automatic updates The Tauri\nJS CLI has a command to install and update all needed dependencies, just run\n`tauri deps install` or `tauri deps update`. ## Manual updates ### Update NPM\nPackages If you are using the `tauri` package: ```bash $ yarn upgrade\n@tauri-apps/cli @tauri-apps/api --latest $ npm install @tauri-apps/cli@latest\n@tauri-apps/api@latest ``` You can also detect what the latest version of Tauri\nis on the command line, using: - `npm outdated @tauri-apps/cli` - `yarn outdated\n@tauri-apps/cli` Alternatively, if you are using the `vue-cli-plugin-tauri`\napproach: ```bash $ yarn upgrade vue-cli-plugin-tauri --latest $ npm install\nvue-cli-plugin-tauri@latest ``` ### Update Cargo Packages Go to\n`src-tauri/Cargo.toml` and change `tauri` to `tauri = { version = \"%version%\" }`\nwhere `%version%` is the version number shown above. (You can just use the\n`MAJOR.MINOR`) version, like `0.9`. Then do the following: ```bash $ cd\nsrc-tauri $ cargo update -p tauri ``` You can also run `cargo outdated -r tauri`\nto get direct information about the core library's latest version.","url":"https://tauri.studio/docs/development/updating-dependencies"},{"id":"prose_docs_distribution_macos_md","title":"macOS Application Distribution","area":"distribution","section":"distribution","headings":["Binary targets","Application bundle customization","Code signing and notarization"],"subHeadings":[],"code":[],"text":"Tauri applications for macOS are distributed either with an [Application\nBundle](https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html)(`.app`\nfiles) or an Apple Disk Image (`.dmg` files). The Tauri CLI automatically\nbundles your application code in these formats, providing options to code sign\nand notarize your application. ## Binary targets You can compile your\napplication targeting Apple Silicon, Intel-based Mac computers or universal\nmacOS binaries. By default, the CLI builds a binary targetting your machine's\narchitecture, but if you are using an Apple Silicon macOS you can compile Intel\nand universal binaries using the `target` option: - `tauri build --target\naarch64-apple-darwin`: targets Apple Silicon for your application; - `tauri\nbuild --target x86_64-apple-darwin`: targets Intel-based Mac computers; - `tauri\nbuild --target universal-apple-darwin`: targets [universal macOS\nbinaries](https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary).\n:::caution - Apple Silicon binaries only runs on Mac computers with Apple\nSilicon. - Intel-based binaries only runs on Intel-based Mac computers and on\nApple Silicion computers under the Rosetta translation. - Universal macOS\nbinaries runs on both architectures. ::: ## Application bundle customization The\nTauri configuration file provides the following options to customize your\napplication bundle: - **Bundle name**:\n[`package.productName`](/docs/api/config/#package.productName). - **Bundle\nversion**: [`package.version`](/docs/api/config/#package.version). -\n**Application category**:\n[`tauri.bundle.category`](/docs/api/config/#tauri.bundle.category). -\n**Copyright**:\n[`tauri.bundle.copyright`](/docs/api/config/#tauri.bundle.copyright). - **Bundle\nicon**: first `.icns` file listed on the\n[`tauri.bundle.icon`](/docs/api/config/#tauri.bundle.icon) array. - **Minimum\nsystem version**:\n[`tauri.bundle.macOS.minimumSystemVersion`](/docs/api/config/#tauri.bundle.macOS.minimumSystemVersion).\n- DMG license file**:\n[`tauri.bundle.macOS.license`](/docs/api/config/#tauri.bundle.macOS.license). -\n[**Entitlements.plist\nfile**](https://developer.apple.com/documentation/bundleresources/entitlements):\n[`tauri.bundle.macOS.entitlements`](/docs/api/config/#tauri.bundle.macOS.entitlements).\n- **Exception domain**: an insecure domain that your application can access such\nas a `localhost` or a remote `http` domain. It is a convenience configuration\naround `NSAppTransportSecurity > NSExceptionDomains` setting\n`NSExceptionAllowsInsecureHTTPLoads` and `NSIncludesSubdomains` to true. See\n[`tauri.bundle.macOS.exceptionDomain`](/docs/api/config/#tauri.bundle.macOS.exceptionDomain).\n- **Bootstrapper**: Instead of launching the app directly, you can configure the\nbundled app to run a script that tries to expose the environment variables to\nthe app; without that you'll have trouble using system programs because the\n`PATH` environment variable isn't correct. Enable it with\n[`tauri.bundle.macOS.useBootstrapper`](/docs/api/config#tauri.bundle.deb.useBootstrapper).\n:::note These options generate the application bundle [Info.plist\nfile](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html).\nYou can extend the generated file with your own `Info.plist` file stored on the\nTauri folder (`src-tauri` by default). The CLI will merge both `.plist` files on\nproduction, and the core layer will embed it on the binary on development. :::\n## Code signing and notarization See the [Code signing guide](./sign-macos.md).","url":"https://tauri.studio/docs/distribution/macos"},{"id":"prose_docs_distribution_publishing_md","title":"App Publishing","area":"distribution","section":"distribution","headings":[],"subHeadings":["1","2"],"code":[],"text":"import Alert from '@theme/Alert' import Command from '@theme/Command' ### 1.\nBuild Your Web App Now that you are ready to package your project, you will need\nto run your framework's or bundler's build command (assuming you're using one,\nof course). Every framework has its own publishing tooling. It is outside of the\nscope of this document to treat them all or keep them up to date. ### 2. Bundle\nyour application with Tauri This command will embed your web assets into a\nsingle binary with your Rust code. The binary itself will be located in\n`src-tauri/target/release/[app name]`, and installers will be located in\n`src-tauri/target/release/bundle/`. Like the `tauri dev` command, the first time\nyou run this, it will take some time to collect the Rust crates and build\neverything - but on subsequent runs it will only need to rebuild your code,\nwhich is much quicker.","url":"https://tauri.studio/docs/distribution/publishing"},{"id":"prose_docs_distribution_sign_macos_md","title":"Code Signing macOS Applications","area":"distribution","section":"distribution","headings":["Requirements","tl","Signing Tauri apps"],"subHeadings":["Creating a signing certificate","Downloading a certificate","Signing the Tauri application","Building the application","Example"],"code":["yml"],"text":"import Alert from '@theme/Alert' This guide provides information on code signing\nand notarization for macOS applications. If you are not utilizing GitHub Actions\nto perform builds of OSX DMGs, you will need to ensure the environment variable\nCI=true exists. For more information refer to Issue #592\n[https://github.com/tauri-apps/tauri/issues/592]. ## Requirements - Xcode 11 or\nabove. - An Apple Developer account enrolled to the [Apple Developer\nProgram](https://developer.apple.com/programs/). ## tl;dr The Tauri code signing\nand notarization process is configured through the following environment\nvariables: - `APPLE_SIGNING_IDENTITY`: the name of the keychain entry that\ncontains the signing certificate. - `APPLE_CERTIFICATE`: base64 string of the\n`.p12` certificate, exported from the keychain. Useful if you don't have the\ncertificate on the keychain (e.g. CI machines). - `APPLE_CERTIFICATE_PASSWORD`:\nthe password for the `.p12` certificate. - `APPLE_ID` and `APPLE_PASSWORD`: your\nApple account email and an [app-specific\npassword](https://support.apple.com/en-ca/HT204397). Only required to notarize\nthe app. - `APPLE_API_ISSUER` and `APPLE_API_KEY`: authentication with an App\nStore Connect API key instead of the Apple ID. Only required to notarize the\napp. ## Signing Tauri apps The first step to sign a macOS application is getting\na signing certificate from the Apple Developer Program. ### Creating a signing\ncertificate To create a new signing certificate you must generate a Certificate\nSigning Request (CSR) file from your Mac computer. [This\nguide](https://help.apple.com/developer-account/#/devbfa00fef7) describes the\nprocess to create a CSR. On your Apple Developer account, navigate to the\n[Certificates, IDs & Profiles\npage](https://developer.apple.com/account/resources/certificates/list) and click\non the `Add` button to open the interface to create a new certificate. Choose\nthe appropriate certificate type (`Apple Distribution` to submit apps to the App\nStore, and `Developer ID Application` to ship apps outside of the App Store).\nUpload your CSR and the certificate will be created. Only the Apple Developer\n`Account Holder` can create Developer ID Application certificates, but it can be\nassociated to a different Apple ID by creating a CSR with a different user email\naddress. ### Downloading a certificate On [Certificates, IDs & Profiles\npage](https://developer.apple.com/account/resources/certificates/list), click on\nthe certificate you want to use and then click on the `Download` button. It will\nsave a `.cer` file that once opened, installs the certificate on the keychain.\nThe name of the keychain entry represents the `signing identity`, which can also\nbe found by executing `$ security find-identity -v -p codesigning`. A signing\ncertificate is only valid if associated with your Apple ID. An invalid\ncertificate won't be listed on the Keychain Access > My Certificates tab or the\n$ security find-identity -v -p codesigning output. ### Signing the Tauri\napplication The signing configuration is provided to the Tauri bundler via\nenvironment variables. You will need to configure the certificate to use and an\noptional authentication configuration to notarize the application. ####\nCertificate environment variables - `APPLE_SIGNING_IDENTITY`: this is the\n`signing identity` we highlighted above. It must be defined to sign apps both\nlocally and on CI machines. Additionally, to simplify the process of code\nsigning on CI, Tauri can install the certificate on the keychain for you if you\ndefine the `APPLE_CERTIFICATE` and `APPLE_CERTIFICATE_PASSWORD` environment\nvariables. 1. Open the `Keychain Access` app and find your certificate's\nkeychain entry. 2. Expand the entry, double click on the key item and select\n`Export \"$KEYNAME\"`. 3. Select the path to save the `.p12` file and define the\nexported certificate password. 4. Convert the `.p12` file to base64 running the\nfollowing script on the terminal: `openssl base64 -in /path/to/certificate.p12\n-out certificate-base64.txt`. 5. Set the contents of the\n`certificate-base64.txt` file to the `APPLE_CERTIFICATE` environment variable.\n6. Set the certificate password to the `APPLE_CERTIFICATE_PASSWORD` environment\nvariable. #### Authentication environment variables These variables are only\nrequired to notarize the application. Notarization is required when using a\nDeveloper ID Application certificate. - `APPLE_ID` and `APPLE_PASSWORD`: to\nauthenticate with your Apple ID, set the `APPLE_ID` to your Apple account email\n(example: `export APPLE_ID=tauri@icloud.com`) and the `APPLE_PASSWORD` to an\n[app-specific password](https://support.apple.com/en-ca/HT204397) for the Apple\naccount. - `APPLE_API_ISSUER` and `APPLE_API_KEY`: alternatively, you can\nauthenticate using an App Store Connect API key. Open the App Store Connect's\n[Users and Access page](https://appstoreconnect.apple.com/access/users), select\nthe `Keys` tab and click on the `Add` button; select a name and the `Developer`\naccess. The `APPLE_API_ISSUER` (`Issuer ID`) is presented above the keys table,\nand the `APPLE_API_KEY` is the value on the `Key ID` column on that table. You\nalso need to download the private key, which can only be done once and is only\nvisible after a page reload (the button is shown on the table row for the newly\ncreated key). The private key file must be saved on `./private_keys`,\n`~/private_keys`, `~/.private_keys` or `~/.appstoreconnect/private_keys`, as\nstated on the `$ xcrun altool --help` command. ### Building the application With\nall these environment variables set, the Tauri bundler will automatically sign\nand notarize your application when you run the `tauri build` command. ###\nExample The following example uses GitHub Actions to sign an application using\nthe [Tauri action](https://github.com/tauri-apps/tauri-action). On GitHub, we\nfirst define the environment variables we listed above as GitHub Secrets. You\ncan view this guide\n[https://docs.github.com/en/actions/reference/encrypted-secrets] to learn about\nGitHub secrets. Once we have established the GitHub Secrets we will create a\nGitHub publish workflow in `.github/workflows/main.yml`: ```yml name: \"publish\"\non: push: branches: - release jobs: publish-tauri: strategy: fail-fast: false\nmatrix: platform: [macos-latest] runs-on: ${{ matrix.platform }} steps: - uses:\nactions/checkout@v2 - name: setup node uses: actions/setup-node@v2 with:\nnode-version: 12 - name: install Rust stable uses: actions-rs/toolchain@v1 with:\ntoolchain: stable - name: install app dependencies and build it run: yarn &&\nyarn build - uses: tauri-apps/tauri-action@v0 env: GITHUB_TOKEN: ${{\nsecrets.GITHUB_TOKEN }} ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}\nAPPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE_PASSWORD:\n${{ secrets.APPLE_CERTIFICATE_PASSWORD }} APPLE_SIGNING_IDENTITY: ${{\nsecrets.APPLE_IDENTITY_ID }} APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_PASSWORD:\n${{ secrets.APPLE_PASSWORD }} with: tagName: app-v__VERSION__ # the action\nautomatically replaces \\_\\_VERSION\\_\\_ with the app version releaseName: \"App\nv__VERSION__\" releaseBody: \"See the assets to download this version and\ninstall.\" releaseDraft: true prerelease: false ``` The workflow pulls the\nsecrets from GitHub and define them as environment variables before building the\napplication using the Tauri action. The output is a GitHub release with the\nsigned and notarized macOS application.","url":"https://tauri.studio/docs/distribution/sign-macos"},{"id":"prose_docs_distribution_sign_windows_md","title":"Windows - Code signing guide locally & with Github Actions","area":"distribution","section":"distribution","headings":["A","B","C","GitHub Secrets","Workflow Modifications"],"subHeadings":[],"code":[null],"text":"import Alert from '@theme/Alert' # Intro Code-signing will add a level of\nauthenticity to your application, while it is not required it can often improve\nthe user experience for your users. # Prerequisites - Windows - you can likely\nuse other platforms, but this tutorial is using Powershell native features. -\nCode signing certificate - you can aqquire one of these on services such as\nDigicert.com, Comodo.com, & Godaddy.com. In this guide we are using Comodo.com -\nA working tauri application # Getting Started There are a few things we will\nhave to do to get our windows installation prepared for code signing. This\nincludes converting our certificate to a speific format, installing this\ncertificate, & then decoding required information from certificate that is\nrequired by tauri. ## A. Convert your `.cer` to `.pfx` 1. You will need the\nfollowing: - certificate file (mine is `cert.cer`) - private key file (mine is\n`private-key.key`) 2. Open up a command prompt and change to your current\ndirectory using `cd Documents/Certs` 3. Convert your `.cer` to a `.pfx` using\n`openssl pkcs12 -export -in cert.cer -inkey private-key.key -out\ncertificate.pfx` 4. You will be prompted to enter an export password **DON'T\nFORGET IT!** ## B. Import your `.pfx` file into the keystore. We will now need\nto import our `.pfx` file. 1. Assign your export password to a variable using\n`$WINDOWS_PFX_PASSWORD = 'MYPASSWORD'` 2. Now Import the certificate using\n`Import-PfxCertificate -FilePath Certs/certificate.pfx -CertStoreLocation\nCert:\\CurrentUser\\My -Password (ConvertTo-SecureString -String\n$env:WINDOWS_PFX_PASSWORD -Force -AsPlainText)` ## C. Prepare Variables 1. We\nwill need the SHA-1 thumbprint of the certificate, you can get this using\n`openssl pkcs12 -info -in certificate.pfx` and look under for following ``` Bag\nAttributes localKeyID: A1 B1 A2 B2 A3 B3 A4 B4 A5 B5 A6 B6 A7 B7 A8 B8 A9 B9 A0\nB0 ``` 2. You will capture the `localKeyID` but with no spaces, in this example\nit would be `A1B1A2B2A3B3A4B4A5B5A6B6A7B7A8B8A9B9A0B0`. This is our\n`certificateThumbprint`. 3. We will need the SHA digest algorythm used for your\ncertificate (Hint: this is likely `sha256` 4. We will also need a timestamp url,\nthis is a time server used to verify the time of the certificate signing. Im\nusing `http://timestamp.comodoca.com` but whoever you got your certificate from\nlikely has one aswell. # Prepare `tauri.conf.json` file 1. Now that we have our\n`certificateThumbprint`, `digestAlgorithm`, & `timestampUrl` we will open up the\n`tauri.conf.json`. 2. In the `tauri.conf.json` you will look for the `tauri` ->\n`bundle` -> `windows` section. You will see there are three variable for the\ninformation we have captured. Fill it out like below. ``` \"windows\": {\n\"certificateThumbprint\": \"A1B1A2B2A3B3A4B4A5B5A6B6A7B7A8B8A9B9A0B0\",\n\"digestAlgorithm\": \"sha256\", \"timestampUrl\": \"http://timestamp.comodoca.com\" }\n``` 3. Save, and run `yarn | yarn build` 4. In the console output you will see\nthe following output. ``` info: signing app info: running signtool \"C:\\\\Program\nFiles (x86)\\\\Windows Kits\\\\10\\\\bin\\\\10.0.19041.0\\\\x64\\\\signtool.exe\" info: \"Done\nAdding Additional Store\\r\\nSuccessfully signed: APPLICATION FILE PATH HERE ```\nwhich shows you have successfully signed the `.exe`. And thats it! You have\nsuccessfully signed your .exe file. # BONUS: Sign your application with GitHub\nActions. We can also create a workflow to sign the application with GitHub\nactions, this will help automate your Publish time. ## GitHub Secrets We will\nneed to add a few GitHub secrets for the proper configuration of the GitHub\nAction. These can be named however you would like. - You can view\n[this](https://docs.github.com/en/actions/reference/encrypted-secrets) guide for\nhow to add GitHub secrets. The secrets we used are as follows | GitHub Secrets |\nValue for Variable | | :---: | :---: | |WINDOWS_CERTIFICATE| Base64 encoded\nversion of your .pfx certificate, can be done using this command `certutil\n-encode certificate.pfx base64cert.txt` |\n|WINDOWS_CERTIFICATE_PASSWORD|Certificate export password used on creation of\ncertificate .pfx| ## Workflow Modifications 1. We will need to add a step in the\nworkflow to properly import the certificate into the windows environment. This\nwork flow accomplishes the following 1. Assign GitHub secrets to environment\nvariables 2. Create a new `certificate` directory 3. Import\n`WINDOWS_CERTIFICATE` into tempCert.txt 4. Use `certutil` to decode the\ntempCert.txt from base64 into a `.pfx` file. 5. Remove tempCert.txt 6. Import\nthe `.pfx` file into the Cert store of Windows & convert the\n`WINDOWS_CERTIFICATE_PASSWORD` to a secure string to be used in the import\ncommand. 2. We will be using the tauri-action publish template available\n[here](https://github.com/tauri-apps/tauri-action) ``` name: \"publish\" on: push:\nbranches: - release jobs: publish-tauri: strategy: fail-fast: false matrix:\nplatform: [macos-latest, ubuntu-latest, windows-latest] runs-on: ${{\nmatrix.platform }} steps: - uses: actions/checkout@v2 - name: setup node uses:\nactions/setup-node@v1 with: node-version: 12 - name: install Rust stable uses:\nactions-rs/toolchain@v1 with: toolchain: stable - name: install webkit2gtk\n(ubuntu only) if: matrix.platform == 'ubuntu-latest' run: | sudo apt-get update\nsudo apt-get install -y webkit2gtk-4.0 - name: install app dependencies and\nbuild it run: yarn && yarn build - uses: tauri-apps/tauri-action@v0 env:\nGITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tagName: app-v__VERSION__ # the\naction automatically replaces \\_\\_VERSION\\_\\_ with the app version releaseName:\n\"App v__VERSION__\" releaseBody: \"See the assets to download this version and\ninstall.\" releaseDraft: true prerelease: false ``` 3. Right above `-name:\ninstall app dependencies and build it` you will want to add the following step\n``` - name: import windows certificate if: matrix.platform == 'windows-latest'\nenv: WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}\nWINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} run: |\nNew-Item -ItemType directory -Path certificate Set-Content -Path\ncertificate/tempCert.txt -Value $env:WINDOWS_PFX certutil -decode\ncertificate/tempCert.txt certificate/certificate.pfx Remove-Item -path\ncertificate -include tempCert.txt Import-PfxCertificate -FilePath\ncertificate/certificate.pfx -CertStoreLocation Cert:\\CurrentUser\\My -Password\n(ConvertTo-SecureString -String $env:WINDOWS_PFX_PASSWORD -Force -AsPlainText)\n``` 4. Save, and push to your repo. 5. You workflow will now be able to import\nyour windows certificate and import it into the github runner, allowing for\nautomated code-signing!","url":"https://tauri.studio/docs/distribution/sign-windows"},{"id":"prose_docs_distribution_updater_md","title":"Updater","area":"distribution","section":"distribution","headings":["Update Requests","Built","Javascript API","Events","Update Server JSON Format","Update File JSON Format","macOS","Windows","Linux"],"subHeadings":["Initialize updater and check if a new version is available","Listen New Update Available","Emit Install and Download","Listen Install Progress"],"code":["js","json","none","bash"],"text":"# Configuration Once you have your Tauri project ready, you need to configure\nthe updater. Add this in tauri.conf.json ```json \"updater\": { \"active\": true,\n\"endpoints\": [ \"https://releases.myapp.com/{{target}}/{{current_version}}\" ],\n\"dialog\": true, \"pubkey\": \"\" } ``` The required keys are \"active\" and\n\"endpoints\", others are optional. \"active\" must be a boolean. By default, it's\nset to false. \"endpoints\" must be an array. The string `{{target}}` and\n`{{current_version}}` are automatically replaced in the URL allowing you\ndetermine [server-side](#update-server-json-format) if an update is available.\nIf multiple endpoints are specified, the updater will fallback if a server is\nnot responding within the pre-defined timeout. \"dialog\" if present must be a\nboolean. By default, it's set to true. If enabled, [events](#events) are\nturned-off as the updater will handle everything. If you need the custom events,\nyou MUST turn off the built-in dialog. \"pubkey\" if present must be a valid\npublic-key generated with Tauri cli. See [Signing updates](#signing-updates). ##\nUpdate Requests Tauri is indifferent to the request the client application\nprovides for update checking. `Accept: application/json` is added to the request\nheaders because Tauri is responsible for parsing the response. For the\nrequirements imposed on the responses and the body format of an update, response\nsee [Server Support](#server-support). Your update request must *at least*\ninclude a version identifier so that the server can determine whether an update\nfor this specific version is required. It may also include other identifying\ncriteria such as operating system version, to allow the server to deliver as\nfine-grained an update as you would like. How you include the version identifier\nor other criteria is specific to the server that you are requesting updates\nfrom. A common approach is to use query parameters,\n[Configuration](#configuration) shows an example of this. ## Built-in dialog By\ndefault, updater uses a built-in dialog API from Tauri. ![New\nUpdate](https://i.imgur.com/UMilB5A.png) The dialog release notes is represented\nby the update `note` provided by the [server](#server-support). If the user\naccepts, the download and install are initialized. The user will be then\nprompted to restart the application. ## Javascript API **Attention, you need to\n_disable built-in dialog_ in your [tauri configuration](#configuration),\notherwise, events aren't emitted and the javascript API will NOT work.** ```js\nimport { checkUpdate, installUpdate } from \"@tauri-apps/api/updater\"; import {\nrelaunch } from \"@tauri-apps/api/process\"; try { const {shouldUpdate, manifest}\n= await checkUpdate(); if (shouldUpdate) { // display dialog await\ninstallUpdate(); // install complete, restart app await relaunch(); } }\ncatch(error) { console.log(error); } ``` ## Events **Attention, you need to\n_disable built-in dialog_ in your [tauri configuration](#configuration),\notherwise, events aren't emitted.** To know when an update is ready to be\ninstalled, you can subscribe to these events: ### Initialize updater and check\nif a new version is available #### If a new version is available, the event\n`tauri://update-available` is emitted. Event: `tauri://update` ### Rust ```rust\nwindow.emit(\"tauri://update\".to_string(), None); ``` ### Javascript ```js import\n{ emit } from \"@tauri-apps/api/event\"; emit(\"tauri://update\"); ``` ### Listen\nNew Update Available Event: `tauri://update-available` Emitted data: ```none\nversion Version announced by the server date Date announced by the server body\nNote announced by the server ``` ### Rust ```rust\nwindow.listen(\"tauri://update-available\".to_string(), move |msg| { println!(\"New\nversion available: {:?}\", msg); }) ``` ### Javascript ```js import { listen }\nfrom \"@tauri-apps/api/event\"; listen(\"tauri://update-available\", function (res)\n{ console.log(\"New version available: \", res); }); ``` ### Emit Install and\nDownload You need to emit this event to initialize the download and listen to\nthe [install progress](#listen-install-progress). Event:\n`tauri://update-install` ### Rust ```rust\nwindow.emit(\"tauri://update-install\".to_string(), None); ``` ### Javascript\n```js import { emit } from \"@tauri-apps/api/event\";\nemit(\"tauri://update-install\"); ``` ### Listen Install Progress Event:\n`tauri://update-status` Emitted data: ```none status [ERROR/PENDING/DONE] error\nString/null ``` PENDING is emitted when the download is started and DONE when\nthe install is complete. You can then ask to restart the application. ERROR is\nemitted when there is an error with the updater. We suggest to listen to this\nevent even if the dialog is enabled. ### Rust ```rust\nwindow.listen(\"tauri://update-status\".to_string(), move |msg| { println!(\"New\nstatus: {:?}\", msg); }) ``` ### Javascript ```js import { listen } from\n\"@tauri-apps/api/event\"; listen(\"tauri://update-status\", function (res) {\nconsole.log(\"New status: \", res); }); ``` # Server Support Your server should\ndetermine whether an update is required based on the [Update\nRequest](#update-requests) your client issues. If an update is required your\nserver should respond with a status code of [200\nOK](http://tools.ietf.org/html/rfc2616#section-10.2.1) and include the [update\nJSON](#update-server-json-format) in the body. To save redundantly downloading\nthe same version multiple times your server must not inform the client to\nupdate. If no update is required your server must respond with a status code of\n[204 No Content](http://tools.ietf.org/html/rfc2616#section-10.2.5). ## Update\nServer JSON Format When an update is available, Tauri expects the following\nschema in response to the update request provided: ```json { \"url\":\n\"https://mycompany.example.com/myapp/releases/myrelease.tar.gz\", \"version\":\n\"0.0.1\", \"notes\": \"Theses are some release notes\", \"pub_date\":\n\"2020-09-18T12:29:53+01:00\", \"signature\": \"\" } ``` The only required keys are\n\"url\" and \"version\", the others are optional. \"pub_date\" if present must be\nformatted according to ISO 8601. \"signature\" if present must be a valid\nsignature generated with Tauri cli. See [Signing updates](#signing-updates). ##\nUpdate File JSON Format The alternate update technique uses a plain JSON file\nmeaning you can store your update metadata on S3, gist, or another static file\nstore. Tauri will check against the name/version field and if the version is\nsmaller than the current one and the platform is available, the update will be\ntriggered. The format of this file is detailed below: ```json { \"name\":\"v1.0.0\",\n\"notes\":\"Test version\", \"pub_date\":\"2020-06-22T19:25:57Z\", \"platforms\": {\n\"darwin\": { \"signature\":\"\",\n\"url\":\"https://github.com/lemarier/tauri-test/releases/download/v1.0.0/app.app.tar.gz\"\n}, \"linux\": { \"signature\":\"\",\n\"url\":\"https://github.com/lemarier/tauri-test/releases/download/v1.0.0/app.AppImage.tar.gz\"\n}, \"win64\": { \"signature\":\"\",\n\"url\":\"https://github.com/lemarier/tauri-test/releases/download/v1.0.0/app.x64.msi.zip\"\n} } } ``` # Bundler (Artifacts) The Tauri bundler will automatically generate\nupdate artifacts if the updater is enabled in `tauri.conf.json` If the bundler\ncan locate your private and pubkey, your update artifacts will be automatically\nsigned. The signature can be found in the `sig` file. The signature can be\nuploaded to GitHub safely or made public as long as your private key is secure.\nYou can see how it's [bundled with the\nCI](https://github.com/tauri-apps/tauri/blob/5b6c7bb6ee3661f5a42917ce04a89d94f905c949/.github/workflows/artifacts-updater.yml#L44)\nand a [sample\ntauri.conf.json](https://github.com/tauri-apps/tauri/blob/5b6c7bb6ee3661f5a42917ce04a89d94f905c949/examples/updater/src-tauri/tauri.conf.json#L52)\n## macOS On MACOS we create a .tar.gz from the whole application. (.app) ```none\ntarget/release/bundle └── osx └── app.app └── app.app.tar.gz (update bundle) └──\napp.app.tar.gz.sig (if signature enabled) ``` ## Windows On Windows we create a\n.zip from the MSI, when downloaded and validated, we run the MSI install.\n```none target/release └── app.x64.msi └── app.x64.msi.zip (update bundle) └──\napp.x64.msi.zip.sig (if signature enabled) ``` ## Linux On Linux, we create a\n.tar.gz from the AppImage. ```none target/release/bundle └── appimage └──\napp.AppImage └── app.AppImage.tar.gz (update bundle) └── app.AppImage.tar.gz.sig\n(if signature enabled) ``` # Signing updates We offer a built-in signature to\nensure your update is safe to be installed. To sign your updates, you need two\nthings. The *Public-key* (pubkey) should be added inside your `tauri.conf.json`\nto validate the update archive before installing. The *Private key* (privkey) is\nused to sign your update and should NEVER be shared with anyone. Also, if you\nlost this key, you'll NOT be able to publish a new update to the current user\nbase (if pubkey is set in tauri.conf.json). It's important to save it at a safe\nplace and you can always access it. To generate your keys you need to use the\nTauri cli. ```bash tauri sign -g -w ~/.tauri/myapp.key ``` You have multiple\noptions available ```bash Tauri updates signer. USAGE: tauri sign [FLAGS]\n[OPTIONS] FLAGS: --force Overwrite private key even if it exists on the\nspecified path -g, --generate Generate keypair to sign files -h, --help Prints\nhelp information --no-password Set empty password for your private key -V,\n--version Prints version information OPTIONS: -p, --password Set private key\npassword when signing -k, --private-key Load the private key from a string -f,\n--private-key-path Load the private key from a file --sign-file Sign the\nspecified file -w, --write-keys Write private key to a file ``` *** Environment\nvariables used to sign with the Tauri `bundler`: If they are set, and\n`tauri.conf.json` expose the public key, the bundler will automatically generate\nand sign the updater artifacts. `TAURI_PRIVATE_KEY` Path or String of your\nprivate key `TAURI_KEY_PASSWORD` Your private key password (optional)","url":"https://tauri.studio/docs/distribution/updater"},{"id":"prose_docs_getting_started_beginning_tutorial_md","title":"Your First Tauri App","area":"getting-started","section":"getting-started","headings":["Vue CLI Plugin Tauri"],"subHeadings":["1","1","2","3","Patterns"],"code":["bash","sh",null],"text":"import Alert from '@theme/Alert' import Command from '@theme/Command' import\nLink from '@docusaurus/Link' :::caution You must have completed all the steps\nrequired for setting up the development environment on your machine. If you\nhaven't done this yet, please see the [setup page for your operating\nsystem](/docs/getting-started/prerequisites). ::: There are two ways to\nintegrate with Tauri depends on your need: - [Start a new Tauri\nproject](#1-start-a-new-tauri-project) - Or [add Tauri to existing\nproject](#1-add-tauri-to-existing-project) ### 1. Start a New Tauri Project\n```bash yarn create tauri-app #OR npx create-tauri-app ``` Just follow the\ninstructions and choose the web frontend framework you prefer.\n`create-tauri-app` will create a template project depends on your inputs. You\ncan go straight to [check `tauri\ninfo`](#3-check-tauri-info-to-make-sure-everything-is-set-up-properly) after\nthis. ### 1. Add Tauri to Existing Project: The Tauri CLI tool helps you build\nyour project, so install it at first. You can install Tauri CLI [using\n`Node.js`](#install-tauri-cli-package-as-a-dev-dependency) or [using\n`Rust`](#alternatively-install-tauri-cli-as-a-cargo-subcommand) #### Install\nTauri CLI package as a dev dependency: ```bash cd project-folder # Not required\nif you already have a package.json: # yarn init # OR # npm init yarn add -D\n@tauri-apps/cli # OR npm install -D @tauri-apps/cli ``` :::note You can install\nTauri as both a local and a global dependency, but we recommend installing it\nlocally. ::: If you decide to use Tauri as a local package with npm (not yarn),\nyou will have to define a custom script to your package.json: ```js\ntitle=package.json { // This content is just a sample \"scripts\": { \"tauri\":\n\"tauri\" } } ``` #### Alternatively, install Tauri CLI as a cargo subcommand:\nThis will install `tauri-cli` as a Cargo subcommand on the cargo binary folder\n(by default on `$HOME/.cargo/bin`): ```bash cargo install tauri-cli --locked\n--version ^1.0.0-rc ``` For more installation options, see [`cargo\ninstall`](https://doc.rust-lang.org/cargo/commands/cargo-install.html#description)\n#### Install Tauri API Package as a Dependency (optional): The `@tauri-apps/api`\npackage is recommended for projects using ES modules or modern build tools such\nas Webpack or Vite. It is the most secure way to access the Tauri APIs. ```bash\nyarn add @tauri-apps/api # OR npm install @tauri-apps/api ``` ### 2. Initialize\nTauri in Your App This command will place a new folder in your current working\ndirectory, `src-tauri`. ```sh └── src-tauri ├── .gitignore ├── Cargo.toml ├──\nrustfmt.toml ├── tauri.conf.json ├── icons │ ├── 128x128.png │ ├──\n128x128@2x.png │ ├── 32x32.png │ ├── Square107x107Logo.png │ ├──\nSquare142x142Logo.png │ ├── Square150x150Logo.png │ ├── Square284x284Logo.png │\n├── Square30x30Logo.png │ ├── Square310x310Logo.png │ ├── Square44x44Logo.png │\n├── Square71x71Logo.png │ ├── Square89x89Logo.png │ ├── StoreLogo.png │ ├──\nicon.icns │ ├── icon.ico │ └── icon.png └── src ├── build.rs ├── cmd.rs └──\nmain.rs ``` ### 3. Check `tauri info` to Make Sure Everything Is Set up\nProperly: Which should return something like: ``` Operating System -\nDarwin(16.7.0) - darwin/x64 Node.js environment Node.js - 12.16.3\n@tauri-apps/cli - 1.0.0-rc.0 @tauri-apps/api - 1.0.0-rc.0 Global packages npm -\n6.14.15 pnpm - Not installed yarn - 1.22.17 Rust environment rustup - 1.24.3\nrustc - 1.58.1 cargo - 1.58.0 toolchain - stable-x86_64-unknown-linux-gnu App\ndirectory structure /node_modules /src-tauri /src /public App tauri.rs -\n1.0.0-rc.0 build-type - bundle CSP - default-src 'self' distDir - ../public\ndevPath - ../public framework - Svelte bundler - Rollup ``` This information can\nbe very helpful when triaging problems. ### Patterns We've also defined prebuilt\nconfigurations called \"Patterns\". They may help you to customize Tauri to fit\nyour needs. [See more about\npatterns](/docs/architecture/patterns/about-patterns). ## Vue CLI Plugin Tauri\nIf you are using Vue CLI, it is recommended to use the official [CLI\nplugin](https://github.com/tauri-apps/vue-cli-plugin-tauri).","url":"https://tauri.studio/docs/getting-started/beginning-tutorial"},{"id":"prose_docs_getting_started_prerequisites_md","title":"Prerequisites","area":"getting-started","section":"getting-started","headings":[],"subHeadings":[],"code":[],"text":"import OSList from '@theme/OSList' - Rust - Node (optional) - OS specific build\ntooling, eg. `build-essential`, `xcode-select` or `C++ build tools` For more\ninformation on platform-specific build tooling, see these guides to get started.\nAfter that, you'll be ready to [make your first Tauri\napp](/docs/getting-started/beginning-tutorial)!","url":"https://tauri.studio/docs/getting-started/prerequisites"},{"id":"prose_docs_getting_started_setting_up_linux_md","title":"Setting Up Linux","area":"getting-started","section":"getting-started","headings":["1","2","3","4","Continue"],"subHeadings":["Optional dependencies","Node","Optional Node","WSL Version 1","WSL Version 2"],"code":["sh","bash"],"text":"import Alert from '@theme/Alert' import Icon from '@theme/Icon' import { Intro }\nfrom '@theme/SetupDocs' import Tabs from '@theme/Tabs'; import TabItem from\n'@theme/TabItem'; ## 1. System Dependencies  ```sh $ sudo apt update && sudo apt\ninstall libwebkit2gtk-4.0-dev \\ build-essential \\ curl \\ wget \\ libssl-dev \\\nlibgtk-3-dev \\ libappindicator3-dev \\ patchelf \\ librsvg2-dev ``` ```sh $ sudo\npacman -Syu && sudo pacman -S --needed \\ webkit2gtk \\ base-devel \\ curl \\ wget \\\nopenssl \\ appmenu-gtk-module \\ gtk3 \\ libappindicator-gtk3 \\ patchelf \\ librsvg\n\\ libvips ``` ```sh $ sudo dnf check-update && sudo dnf install\nwebkit2gtk3-devel.x86_64 \\ openssl-devel \\ curl \\ wget \\ libappindicator-gtk3 \\\npatchelf \\ librsvg2-devel \\ && sudo dnf group install \"C Development Tools and\nLibraries\" ``` ### Optional dependencies: - `libappindicator`: needed to use the\nsystem tray feature. - `patchelf` and `librsvg`: needed to bundle `AppImage`. ##\n2. Node.js Runtime and Package Manager  ### Node.js (npm included) We recommend\nusing nvm to manage your Node.js runtime. It allows you to easily switch\nversions and update Node.js. ```sh $ curl -o-\nhttps://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash ``` We\nhave audited this bash script, and it does what it says it is supposed to do.\nNevertheless, before blindly curl-bashing a script, it is always wise to look at\nit first. Here is the file as a mere download link\n[https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh]. Once nvm is\ninstalled, close and reopen your terminal, then install the latest version of\nNode.js and npm: ```sh $ nvm install node --latest-npm $ nvm use node ``` If you\nhave any problems with nvm, please consult their project readme\n[https://github.com/nvm-sh/nvm]. ### Optional Node.js Package Manager You may\nwant to use an alternative to npm: - Yarn [https://yarnpkg.com/getting-started],\nis preferred by Tauri's team - pnpm [https://pnpm.js.org/en/installation] ## 3.\nRustc and Cargo Package Manager  The following command will install rustup\n[https://rustup.rs/], the official installer for Rust\n[https://www.rust-lang.org/]. ```bash $ curl --proto '=https' --tlsv1.2 -sSf\nhttps://sh.rustup.rs | sh ``` We have audited this bash script, and it does what\nit says it is supposed to do. Nevertheless, before blindly curl-bashing a\nscript, it is always wise to look at it first. Here is the file as a mere\ndownload link [https://sh.rustup.rs]. To make sure that Rust has been installed\nsuccessfully, run the following command: ```sh $ rustc --version latest update\non 2019-12-19, rust version 1.40.0 ``` You may need to restart your terminal if\nthe command does not work. ## 4. For Windows Subsystem for Linux (WSL) Users  In\norder to run a graphical application with WSL, you need to download **one** of\nthese X servers: Xming, Cygwin X, and vcXsrv. Since vcXsrv has been used\ninternally, it's the one we recommend to install. ### WSL Version 1 Open the X\nserver and then run `export DISPLAY=:0` in the terminal. You should now be able\nto run any graphical application via the terminal. ### WSL Version 2 You'll need\nto run a command that is slightly more complex than WSL 1: `export DISPLAY=$(cat\n/etc/resolv.conf | grep nameserver | awk '{print $2}'):0` and you need to add\n`-ac` to the X server as an argument. Note: if for some reason this command\ndoesn't work you can use an alternative command such as: `export DISPLAY=$(cat\n/etc/resolv.conf | grep nameserver | sed 's/.* //g'):0` or you can manually find\nthe Address using `cat /etc/resolve.conf | grep nameserver`. Don't forget that\nyou'll have to use the \"export\" command anytime you want to use a graphical\napplication, for each newly opened terminal. You can download some examples to\ntry with `sudo apt-get install x11-apps`. xeyes is always a good one. It can be\nhandy when troubleshooting WSL issues. ## Continue Now that you have set up the\nLinux-specific dependencies for Tauri, learn how to [add Tauri to your\nproject](/docs/getting-started/beginning-tutorial).","url":"https://tauri.studio/docs/getting-started/setting-up-linux"},{"id":"prose_docs_getting_started_setting_up_macos_md","title":"Setting Up macOS","area":"getting-started","section":"getting-started","headings":["1","2","3","Continue"],"subHeadings":["Node","Optional Node"],"code":["sh",null],"text":"import Alert from '@theme/Alert' import { Intro } from '@theme/SetupDocs' import\nIcon from '@theme/Icon' ## 1. System Dependencies  You will need to have\nHomebrew [https://brew.sh/] installed to run the following command. ```sh $ brew\ninstall gcc ``` You will also need to make sure `xcode` is installed. ```sh $\nxcode-select --install ``` ## 2. Node.js Runtime and Package Manager  ###\nNode.js (npm included) We recommend using nvm to manage your Node.js runtime. It\nallows you to easily switch versions and update Node.js. ```sh $ curl -o-\nhttps://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash ``` We\nhave audited this bash script, and it does what it says it is supposed to do.\nNevertheless, before blindly curl-bashing a script, it is always wise to look at\nit first. Here is the file as a mere download link\n[https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh]. Once nvm is\ninstalled, close and reopen your terminal, then install the latest version of\nNode.js and npm: ```sh $ nvm install node --latest-npm $ nvm use node ``` If you\nhave any problems with nvm, please consult their project readme\n[https://github.com/nvm-sh/nvm]. ### Optional Node.js Package Manager You may\nwant to use an alternative to npm: - Yarn [https://yarnpkg.com/getting-started],\nis preferred by Tauri's team - pnpm [https://pnpm.js.org/en/installation] ## 3.\nRustc and Cargo Package Manager  The following command will install rustup\n[https://rustup.rs/], the official installer for Rust\n[https://www.rust-lang.org/]. ``` $ curl --proto '=https' --tlsv1.2 -sSf\nhttps://sh.rustup.rs | sh ``` We have audited this bash script, and it does what\nit says it is supposed to do. Nevertheless, before blindly curl-bashing a\nscript, it is always wise to look at it first. Here is the file as a mere\ndownload link [https://sh.rustup.rs]. To make sure that Rust has been installed\nsuccessfully, run the following command: ```sh $ rustc --version latest update\non 2019-12-19, rust version 1.40.0 ``` You may need to restart your terminal if\nthe command does not work. ## Continue Now that you have set up the\nmacOS-specific dependencies for Tauri, learn how to [add Tauri to your\nproject](/docs/getting-started/beginning-tutorial).","url":"https://tauri.studio/docs/getting-started/setting-up-macos"},{"id":"prose_docs_getting_started_setting_up_windows_md","title":"Setting Up Windows","area":"getting-started","section":"getting-started","headings":["1","2","3","4","Continue"],"subHeadings":["Node","Optional Node"],"code":["powershell"],"text":"import Alert from '@theme/Alert' import Icon from '@theme/Icon' import { Intro }\nfrom '@theme/SetupDocs' :::note For those using the Windows Subsystem for Linux\n(WSL) please refer to our [Linux specific\ninstructions](/docs/getting-started/setting-up-linux) instead. ::: ## 1. System\nDependencies  You'll need to install Microsoft Visual Studio C++ build tools.\nDownload the installer here\n[https://visualstudio.microsoft.com/visual-cpp-build-tools/], and then run it.\nWhen it asks you what packages you would like to install, select C++ Build Tools\nand make sure the Windows SDK is selected. This is a big download (over 1GB) and\ntakes the most time, so go grab a coffee. You may need to uninstall the 2017\nversion of the build tools if you have them. There are reports of Tauri not\nworking with both the 2017 and 2019 versions installed. ## 2. Node.js Runtime\nand Package Manager  ### Node.js (npm included) We recommend using nvm-windows\n[https://github.com/coreybutler/nvm-windows#installation--upgrades] to manage\nyour Node.js runtime. It allows you to easily switch versions and update\nNode.js. Then run the following from an Administrative PowerShell and press Y\nwhen prompted: ```powershell # BE SURE YOU ARE IN AN ADMINISTRATIVE PowerShell!\nnvm install latest nvm use {{latest}} # Replace with your latest downloaded\nversion ``` This will install the most recent version of Node.js with npm. ###\nOptional Node.js Package Manager You may want to use an alternative to npm: -\nYarn [https://yarnpkg.com/getting-started], is preferred by Tauri's team - pnpm\n[https://pnpm.js.org/en/installation] ## 3. Rustc and Cargo Package Manager  Now\nyou will need to install Rust [https://www.rust-lang.org/]. The easiest way to\ndo this is to use rustup [https://rustup.rs/], the official installer. - 64-bit\ndownload link [https://win.rustup.rs/x86_64] - 32-bit download link\n[https://win.rustup.rs/i686] Download and install the proper variant for your\ncomputer's architecture. ## 4. Install WebView2 WebView2 is pre-installed in\nWindows 11. Finally, you will need to install WebView2. The best way to do this\nis to download and run the Evergreen Bootstrapper from [this\npage](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section).\nIf you have problems of any kind after following these instructions, we\nrecommend that you reboot your computer before developing a Tauri project to\nensure that everything works as expected. ## Continue Now that you have set up\nthe Windows-specific dependencies for Tauri, learn how to [add Tauri to your\nproject](/docs/getting-started/beginning-tutorial).","url":"https://tauri.studio/docs/getting-started/setting-up-windows"},{"id":"prose_docs_guides_cli_md","title":"Making Your Own CLI","area":"guides","section":"guides","headings":["Base Configuration","Adding Arguments","Subcommands","Reading the matches","Complete documentation"],"subHeadings":["Positional Arguments","Named Arguments","Flag Arguments","Rust","JavaScript"],"code":["rust","js"],"text":"import Alert from '@theme/Alert' Tauri enables your app to have a CLI through\nclap [https://github.com/clap-rs/clap], a robust command line argument parser.\nWith a simple CLI definition in your `tauri.conf.json` file, you can define your\ninterface and read its argument matches map on JavaScript and/or Rust. ## Base\nConfiguration Under `tauri.conf.json`, you have the following structure to\nconfigure the interface: ```js title=src-tauri/tauri.conf.json { \"tauri\": {\n\"cli\": { \"description\": \"\", // command description that's shown on help\n\"longDescription\": \"\", // command long description that's shown on help\n\"beforeHelp\": \"\", // content to show before the help text \"afterHelp\": \"\", //\ncontent to show after the help text \"args\": [], // list of arguments of the\ncommand, we'll explain it later \"subcommands\": { \"subcommand-name\": { //\nconfigures a subcommand that is accessible // with `$ ./app subcommand-name\n--arg1 --arg2 --etc` // configuration as above, with \"description\", \"args\", etc.\n} } } } } ``` All JSON configurations here are just samples, many other fields\nhave been omitted for the sake of clarity. ## Adding Arguments The `args` array\nrepresents the list of arguments accepted by its command or subcommand. You can\nfind more details about the way to configure them here [/docs/api/config#tauri].\n### Positional Arguments A positional argument is identified by its position in\nthe list of arguments. With the following configuration: ```json\ntitle=src-tauri/tauri.conf.json:tauri.cli { \"args\": [ { \"name\": \"source\",\n\"index\": 1, \"takesValue\": true }, { \"name\": \"destination\", \"index\": 2,\n\"takesValue\": true } ] } ``` Users can run your app as `$ ./app tauri.txt\ndest.txt` and the arg matches map will define `source` as `\"tauri.txt\"` and\n`destination` as `\"dest.txt\"`. ### Named Arguments A named argument is a (key,\nvalue) pair where the key identifies the value. With the following\nconfiguration: ```json title=src-tauri/tauri.conf.json:tauri.cli { \"args\": [ {\n\"name\": \"type\", \"short\": \"t\", \"takesValue\": true, \"multiple\": true,\n\"possibleValues\": [\"foo\", \"bar\"] } ] } ``` Users can run your app as `$ ./app\n--type foo bar`, `$ ./app -t foo -t bar` or `$ ./app --type=foo,bar` and the arg\nmatches map will define `type` as `[\"foo\", \"bar\"]`. ### Flag Arguments A flag\nargument is a standalone key whose presence or absence provides information to\nyour application. With the following configuration: ```js\ntitle=src-tauri/tauri.conf.json:tauri.cli { \"args\": [ \"name\": \"verbose\",\n\"short\": \"v\", \"multipleOccurrences\": true ] } ``` Users can run your app as `$\n./app -v -v -v`, `$ ./app --verbose --verbose --verbose` or `$ ./app -vvv` and\nthe arg matches map will define `verbose` as `true`, with `occurrences = 3`. ##\nSubcommands Some CLI applications has additional interfaces as subcommands. For\ninstance, the `git` CLI has `git branch`, `git commit` and `git push`. You can\ndefine additional nested interfaces with the `subcommands` array: ```js\ntitle=src-tauri/tauri.conf.json:tauri { \"cli\": { ... \"subcommands\": { \"branch\":\n{ \"args\": [] }, \"push\": { \"args\": [] } } } } ``` Its configuration is the same\nas the root application configuration, with the `description`,\n`longDescription`, `args`, etc. ## Reading the matches ### Rust ```rust use\ntauri::api::cli::get_matches; fn main() { let context =\ntauri::generate_context!(); let cli_config =\ncontext.config().tauri.cli.clone().unwrap(); match get_matches(&cli_config) { //\n`matches` here is a Struct with { args, subcommand }. // `args` is `HashMap`\nwhere `ArgData` is a struct with { value, occurances }. // `subcommand` is\n`Option>` where `SubcommandMatches` is a struct with { name, matches }.\nOk(matches) => { println!(\"{:?}\", matches) } Err(_) => {} };\ntauri::Builder::default() .run(context) .expect(\"error while running tauri\napplication\"); } ``` ### JavaScript ```js import { getMatches } from\n'@tauri-apps/api/cli' getMatches().then((matches) => { // do something with the\n{ args, subcommand } matches }) ``` ## Complete documentation You can find more\nabout the CLI configuration here [/docs/api/config#tauri].","url":"https://tauri.studio/docs/guides/cli"},{"id":"prose_docs_guides_command_md","title":"Creating Rust Commands","area":"guides","section":"guides","headings":["Basic Example","Passing Arguments","Returning Data","Error Handling","Async Commands","Accessing the Window in Commands","Accessing an AppHandle in Commands","Accessing managed state","Creating Multiple Commands","Complete Example"],"subHeadings":[],"code":["rust","js"],"text":"import Alert from '@theme/Alert' Tauri provides a simple yet powerful \"command\"\nsystem for calling Rust functions from your web app. Commands can accept\narguments and return values. They can also return errors and be `async`. ##\nBasic Example Commands are defined in your `src-tauri/src/main.rs` file. To\ncreate a command, just add a function and annotate it with `#[tauri::command]`:\n```rust #[tauri::command] fn my_custom_command() { println!(\"I was invoked from\nJS!\"); } ``` You will have to provide a list of your commands to the builder\nfunction like so: ```rust // Also in main.rs fn main() {\ntauri::Builder::default() // This is where you pass in your commands\n.invoke_handler(tauri::generate_handler![my_custom_command])\n.run(tauri::generate_context!()) .expect(\"failed to run app\"); } ``` Now, you\ncan invoke the command from your JS code: ```js // With the Tauri API npm\npackage: import { invoke } from '@tauri-apps/api/tauri' // With the Tauri global\nscript, enabled when `tauri.conf.json > build > withGlobalTauri` is set to true:\nconst invoke = window.__TAURI__.invoke // Invoke the command\ninvoke('my_custom_command') ``` ## Passing Arguments Your command handlers can\ntake arguments: ```rust #[tauri::command] fn my_custom_command(invoke_message:\nString) { println!(\"I was invoked from JS, with this message: {}\",\ninvoke_message); } ``` Arguments should be passed as a JSON object with\ncamelCase keys: ```js invoke('my_custom_command', { invokeMessage: 'Hello!' })\n``` Arguments can be of any type, as long as they implement\n[serde::Deserialize](https://serde.rs/derive.html). ## Returning Data Command\nhandlers can return data as well: ```rust #[tauri::command] fn\nmy_custom_command() -> String { \"Hello from Rust!\".into() } ``` The `invoke`\nfunction returns a promise that resolves with the returned value: ```js\ninvoke('my_custom_command').then((message) => console.log(message)) ``` Returned\ndata can be of any type, as long as it implements\n[Serde::Serialize](https://serde.rs/derive.html). ## Error Handling If your\nhandler could fail and needs to be able to return an error, have the function\nreturn a `Result`: ```rust #[tauri::command] fn my_custom_command() -> Result {\n// If something fails Err(\"This failed!\".into()) // If it worked Ok(\"This\nworked!\".into()) } ``` If the command returns an error, the promise will reject,\notherwise it resolves: ```js invoke('my_custom_command') .then((message) =>\nconsole.log(message)) .catch((error) => console.error(error)) ``` ## Async\nCommands Async commands are executed on a separate thread using the async\nruntime [https://docs.rs/tauri/1.0.0-rc.0/tauri/async_runtime/fn.spawn.html].\nCommands without the async keyword are executed on the main thread, unless\ndefined with #[tauri::command(async)]. If your command needs to run\nasynchronously, simply declare it as `async`: ```rust #[tauri::command] async fn\nmy_custom_command() { // Call another async function and wait for it to finish\nlet result = some_async_function().await; println!(\"Result: {}\", result); } ```\nSince invoking the command from JS already returns a promise, it works just like\nany other command: ```js invoke('my_custom_command').then(() =>\nconsole.log('Completed!')) ``` ## Accessing the Window in Commands Commands can\naccess the `Window` instance that invoked the message: ```rust #[tauri::command]\nasync fn my_custom_command(window: tauri::Window) { println!(\"Window: {}\",\nwindow.label()); } ``` ## Accessing an AppHandle in Commands Commands can access\nan `AppHandle` instance: ```rust #[tauri::command] async fn\nmy_custom_command(app_handle: tauri::AppHandle) { let app_dir =\napp_handle.path_resolver().app_dir(); use tauri::GlobalShortcutManager;\napp_handle.global_shortcut_manager().register(\"CTRL + U\", move || {}); } ``` ##\nAccessing managed state Tauri can manage state using the `manage` function on\n`tauri::Builder`. The state can be accessed on a command using `tauri::State`:\n```rust struct MyState(String); #[tauri::command] fn my_custom_command(state:\ntauri::State) { assert_eq!(state.0 == \"some state value\", true); } fn main() {\ntauri::Builder::default() .manage(MyState(\"some state value\".into()))\n.invoke_handler(tauri::generate_handler![my_custom_command])\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ## Creating Multiple Commands The\n`tauri::generate_handler!` macro takes an array of commands. To register\nmultiple commands, you cannot call invoke_handler multiple times. Only the last\ncall will be used. You must pass each command to a single call of\n`tauri::generate_handler!`. ```rust #[tauri::command] fn cmd_a() -> String {\n\"Command a\" } #[tauri::command] fn cmd_b() -> String { \"Command b\" } fn main() {\ntauri::Builder::default() .invoke_handler(tauri::generate_handler![cmd_a,\ncmd_b]) .run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ## Complete Example Any or all of the above features can be\ncombined: ```rust title=main.rs // Definition in main.rs struct Database;\n#[derive(serde::Serialize)] struct CustomResponse { message: String, other_val:\nusize, } async fn some_other_function() -> Option { Some(\"response\".into()) }\n#[tauri::command] async fn my_custom_command( window: tauri::Window, number:\nusize, database: tauri::State<'_, Database>, ) -> Result { println!(\"Called from\n{}\", window.label()); let result: Option = some_other_function().await; if let\nSome(message) = result { Ok(CustomResponse { message, other_val: 42 + number, })\n} else { Err(\"No result\".into()) } } fn main() { tauri::Builder::default()\n.manage(Database {})\n.invoke_handler(tauri::generate_handler![my_custom_command])\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ```js // Invocation from JS invoke('my_custom_command', {\nnumber: 42, }) .then((res) => console.log(`Message: ${res.message}, Other Val:\n${res.other_val}`) ) .catch((e) => console.error(e)) ```","url":"https://tauri.studio/docs/guides/command"},{"id":"prose_docs_guides_events_md","title":"Events","area":"guides","section":"guides","headings":["Frontend","Backend"],"subHeadings":["Global events","Window","Global events","Window"],"code":["ts","rust"],"text":"The Tauri event system is a multi-producer multi-consumer communication\nprimitive that allows message passing between the frontend and the backend. It\nis analogous to the command system, but payload type check must be written on\nthe event handler and it simplifies communication from the backend to the\nfrontend, working like a channel. A Tauri application can listen and emit to\nglobal and window-specific events. Usage from the frontend and the backend are\ndescribed below. ## Frontend The event system is accessible on the frontend on\nthe `event` and `window` modules of the `@tauri-apps/api` package. ### Global\nevents To use the global event channel, import the `event` module and use the\n`emit` and `listen` functions: ```ts import { emit, listen } from\n'@tauri-apps/api/event' // listen to the `click` event and get a function to\nremove the event listener // there's also a `once` function that subscribes to\nan event and automatically unsubscribes the listener on the first event const\nunlisten = await listen('click', event => { // event.event is the event name\n(useful if you want to use a single callback fn for multiple event types) //\nevent.payload is the payload object }) // emits the `click` event with the\nobject payload emit('click', { theMessage: 'Tauri is awesome!' }) ``` ###\nWindow-specific events Window-specific events are exposed on the `window`\nmodule. ```ts import { appWindow, WebviewWindow } from '@tauri-apps/api/window'\n// emit an event that are only visible to the current window\nappWindow.emit('event', { message: 'Tauri is awesome!' }) // create a new\nwebview window and emit an event only to that window const webview = new\nWebviewWindow('window') webview.emit('event') ``` ## Backend On the backend, the\nglobal event channel is exposed on the `App` struct, and window-specific events\ncan be emitted using the `Window` trait. ### Global events ```rust use\ntauri::Manager; // the payload type must implement `Serialize`. // for global\nevents, it also must implement `Clone`. #[derive(Clone, serde::Serialize)]\nstruct Payload { message: String, } fn main() { tauri::Builder::default()\n.setup(|app| { // listen to the `event-name` (emitted on any window) let id =\napp.listen_global(\"event-name\", |event| { println!(\"got event-name with payload\n{:?}\", event.payload()); }); // unlisten to the event using the `id` returned on\nthe `listen_global` function // an `once_global` API is also exposed on the\n`App` struct app.unlisten(id); // emit the `event-name` event to all webview\nwindows on the frontend app.emit_all(\"event-name\", Payload { message: \"Tauri is\nawesome!\".into() }).unwrap(); Ok(()) }) .run(tauri::generate_context!())\n.expect(\"failed to run app\"); } ``` ### Window-specific events To use the\nwindow-specific event channel, a `Window` object can be obtained on a command\nhandler or with the `get_window` function: ```rust use tauri::{Manager, Window};\n// the payload type must implement `Serialize`. #[derive(serde::Serialize)]\nstruct Payload { message: String, } // init a background process on the command,\nand emit periodic events only to the window that used the command\n#[tauri::command] fn init_process(window: Window) { std::thread::spawn(move || {\nloop { window.emit(\"event-name\", Payload { message: \"Tauri is awesome!\".into()\n}).unwrap(); } }); } fn main() { tauri::Builder::default() .setup(|app| { //\n`main` here is the window label; it is defined on the window creation or under\n`tauri.conf.json` // the default value is `main`. note that it must be unique\nlet main_window = app.get_window(\"main\").unwrap(); // listen to the `event-name`\n(emitted on the `main` window) let id = main_window.listen(\"event-name\", |event|\n{ println!(\"got window event-name with payload {:?}\", event.payload()); }); //\nunlisten to the event using the `id` returned on the `listen` function // an\n`once` API is also exposed on the `Window` struct main_window.unlisten(id); //\nemit the `event-name` event to the `main` window main_window.emit(\"event-name\",\nPayload { message: \"Tauri is awesome!\".into() }).unwrap(); Ok(()) })\n.invoke_handler(tauri::generate_handler![init_process])\n.run(tauri::generate_context!()) .expect(\"failed to run app\"); } ```","url":"https://tauri.studio/docs/guides/events"},{"id":"prose_docs_guides_icons_md","title":"Icons","area":"guides","section":"guides","headings":[],"subHeadings":[],"code":["sh","json"],"text":"import Command from '@theme/Command' import Alert from '@theme/Alert' Tauri\nships with a default iconset based on its logo. This is probably NOT what you\nwant when you ship your application. To remedy this common situation, Tauri\nprovides the `icon` command that will take an input file (\"./app-icon.png\" by\ndefault) and create all the icons needed for the various platforms: ```sh\nOptions --help, -h Displays this message --log, l Logging [boolean] --icon, i\nSource icon (png, 1240x1240 with transparency) --target, t Target folder\n(default: 'src-tauri/icons') --compression, c Compression type\n[pngquant|optipng|zopfli] ``` These will be placed in your `src-tauri/icons`\nfolder where they will automatically be included in your built app. If you need\nto source your icons from some other location, you can edit this part of the\n`src-tauri/tauri.conf.json` file: ```json { \"tauri\": { \"bundle\": { \"icon\": [\n\"icons/32x32.png\", \"icons/128x128.png\", \"icons/128x128@2x.png\",\n\"icons/icon.icns\", \"icons/icon.ico\" ] } } } ``` - icon.icns = macOS - icon.ico =\nMS Windows - \\*.png = Linux","url":"https://tauri.studio/docs/guides/icons"},{"id":"prose_docs_guides_menu_md","title":"Window Menu","area":"guides","section":"guides","headings":[],"subHeadings":["Creating a menu","Adding the menu to all windows","Adding the menu to a specific window","Listening to events on custom menu items","Updating menu items"],"code":["rust"],"text":"Native application menus can be attached to a window. ### Creating a menu To\ncreate a native window menu, import the `Menu`, `Submenu`, `MenuItem` and\n`CustomMenuItem` types. The `MenuItem` enum contains a collection of\nplatform-specific items (currently not implemented on Windows). The\n`CustomMenuItem` allows you to create your own menu items and add special\nfunctionality to them. ```rust use tauri::{CustomMenuItem, Menu, MenuItem,\nSubmenu}; ``` Create a `Menu` instance: ```rust // here `\"quit\".to_string()`\ndefines the menu item id, and the second parameter is the menu item label. let\nquit = CustomMenuItem::new(\"quit\".to_string(), \"Quit\"); let close =\nCustomMenuItem::new(\"close\".to_string(), \"Close\"); let submenu =\nSubmenu::new(\"File\", Menu::new().add_item(quit).add_item(close)); let menu =\nMenu::new() .add_native_item(MenuItem::Copy)\n.add_item(CustomMenuItem::new(\"hide\", \"Hide\")) .add_submenu(submenu); ``` ###\nAdding the menu to all windows The defined menu can be set to all windows using\nthe `menu` API on the `tauri::Builder` struct: ```rust use\ntauri::{CustomMenuItem, Menu, MenuItem, Submenu}; fn main() { let menu =\nMenu::new(); // configure the menu tauri::Builder::default() .menu(menu)\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ### Adding the menu to a specific window You can create a\nwindow and set the menu to be used. This allows defining a specific menu set for\neach application window. ```rust use tauri::{CustomMenuItem, Menu, MenuItem,\nSubmenu}; use tauri::WindowBuilder; fn main() { let menu = Menu::new(); //\nconfigure the menu tauri::Builder::default() .create_window(\n\"main-window\".to_string(), tauri::WindowUrl::App(\"index.html\".into()), move\n|window_builder, webview_attributes| { (window_builder.menu(menu),\nwebview_attributes) }, ) .run(tauri::generate_context!()) .expect(\"error while\nrunning tauri application\"); } ``` ### Listening to events on custom menu items\nEach `CustomMenuItem` triggers an event when clicked. Use the `on_menu_event`\nAPI to handle them, either on the global `tauri::Builder` or on an specific\nwindow. #### Listening to events on global menus ```rust use\ntauri::{CustomMenuItem, Menu, MenuItem}; fn main() { let menu = vec![]; //\ninsert the menu array here tauri::Builder::default() .menu(menu)\n.on_menu_event(|event| { match event.menu_item_id() { \"quit\" => {\nstd::process::exit(0); } \"close\" => { event.window().close().unwrap(); } _ => {}\n} }) .run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` #### Listening to events on window menus ```rust use\ntauri::{CustomMenuItem, Menu, MenuItem}; use tauri::{Manager, WindowBuilder}; fn\nmain() { let menu = vec![]; // insert the menu array here\ntauri::Builder::default() .create_window( \"main-window\".to_string(),\ntauri::WindowUrl::App(\"index.html\".into()), move |window_builder,\nwebview_attributes| { (window_builder.menu(menu), webview_attributes) }, )\n.setup(|app| { let window = app.get_window(\"main-window\").unwrap(); let window_\n= window.clone(); window.on_menu_event(move |event| { match\nevent.menu_item_id().as_str() { \"quit\" => { std::process::exit(0); } \"close\" =>\n{ window_.close().unwrap(); } _ => {} } }); Ok(()) })\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ### Updating menu items The `Window` struct has a\n`menu_handle` method, which allows updating menu items: ```rust fn main() {\ntauri::Builder::default() .setup(|app| { let main_window =\napp.get_window(\"main\").unwrap(); let menu_handle = main_window.menu_handle();\nstd::thread::spawn(move || { // you can also `set_selected`, `set_enabled` and\n`set_native_image` (macOS only). menu_handle.get_item(\"item_id\").set_title(\"New\ntitle\"); }) Ok(()) }) } ```","url":"https://tauri.studio/docs/guides/menu"},{"id":"prose_docs_guides_multiwindow_md","title":"Multiwindow","area":"guides","section":"guides","headings":[],"subHeadings":[],"code":[],"text":"Manage multiple windows on a single application.","url":"https://tauri.studio/docs/guides/multiwindow"},{"id":"prose_docs_guides_plugin_md","title":"Writing Tauri Plugins","area":"guides","section":"guides","headings":["Writing a Plugin","Using a plugin","Conventions","Official Tauri Plugins"],"subHeadings":[],"code":["rust"],"text":"import Alert from '@theme/Alert' Plugins allow you to hook into the Tauri\napplication lifecycle and introduce new commands. ## Writing a Plugin To write a\nplugin you just need to implement the `tauri::plugin::Plugin` trait: ```rust use\ntauri::{plugin::{Plugin, Result as PluginResult}, Runtime, PageLoadPayload,\nWindow, Invoke, AppHandle}; struct MyAwesomePlugin { invoke_handler: Box) + Send\n+ Sync>, // plugin state, configuration fields } // the plugin custom command\nhandlers if you choose to extend the API. #[tauri::command] // this will be\naccessible with `invoke('plugin:awesome|initialize')`. // where `awesome` is the\nplugin name. fn initialize() {} #[tauri::command] // this will be accessible\nwith `invoke('plugin:awesome|do_something')`. fn do_something() {} impl\nMyAwesomePlugin { // you can add configuration fields here, // see\nhttps://doc.rust-lang.org/1.0.0/style/ownership/builders.html pub fn new() ->\nSelf { Self { invoke_handler: Box::new(tauri::generate_handler![initialize,\ndo_something]), } } } impl Plugin for MyAwesomePlugin { /// The plugin name.\nMust be defined and used on the `invoke` calls. fn name(&self) -> &'static str {\n\"awesome\" } /// The JS script to evaluate on initialization. /// Useful when\nyour plugin is accessible through `window` /// or needs to perform a JS task on\napp initialization /// e.g. \"window.awesomePlugin = { ... the plugin interface\n}\" fn initialization_script(&self) -> Option { None } /// initialize plugin with\nthe config provided on `tauri.conf.json > plugins > $yourPluginName` or the\ndefault value. fn initialize(&mut self, app: &AppHandle, config:\nserde_json::Value) -> PluginResult<()> { Ok(()) } /// Callback invoked when the\nWindow is created. fn created(&mut self, window: Window) {} /// Callback invoked\nwhen the webview performs a navigation. fn on_page_load(&mut self, window:\nWindow, payload: PageLoadPayload) {} /// Extend the invoke handler. fn\nextend_api(&mut self, message: Invoke) { (self.invoke_handler)(message) } } ```\nNote that each function on the `Plugin` trait is optional, except the `name`\nfunction. ## Using a plugin To use a plugin, just pass an instance of the\n`MyAwesomePlugin` struct to the App's `plugin` method: ```rust fn main() { let\nawesome_plugin = MyAwesomePlugin::new(); tauri::Builder::default()\n.plugin(awesome_plugin) .run(tauri::generate_context!()) .expect(\"failed to run\napp\"); } ``` ## Conventions - Plugins should have a clear name with\n`tauri-plugin-` prefix. - Include `tauri-plugin` keyword in\n`Cargo.toml`/`package.json`. - Document your plugin in English. - Add an example\napp showcasing your plugin. ## Official Tauri Plugins -\n[Stronghold](https://github.com/tauri-apps/tauri-plugin-stronghold) -\n[Authenticator](https://github.com/tauri-apps/tauri-plugin-authenticator) -\n[Logging](https://github.com/tauri-apps/tauri-plugin-log) -\n[SQL](https://github.com/tauri-apps/tauri-plugin-sql) -\n[WebSocket](https://github.com/tauri-apps/tauri-plugin-websocket) - [Restoring\nwindow state](https://github.com/tauri-apps/tauri-plugin-window-state) -\n[Store](https://github.com/tauri-apps/tauri-plugin-store)","url":"https://tauri.studio/docs/guides/plugin"},{"id":"prose_docs_guides_splashscreen_md","title":"Splashscreen","area":"guides","section":"guides","headings":[],"subHeadings":["Setup","Waiting for Webpage","Waiting for Rust"],"code":["diff",null],"text":"import Link from '@docusaurus/Link' If your webpage could take some time to\nload, or if you need to run an initialization procedure in Rust before\ndisplaying your main window, a splashscreen could improve the loading experience\nfor the user. ### Setup First, create a `splashscreen.html` in your `distDir`\nthat contains the HTML code for a splashscreen. Then, update your\n`tauri.conf.json` like so: ```diff \"windows\": [ { \"title\": \"Tauri App\", \"width\":\n800, \"height\": 600, \"resizable\": true, \"fullscreen\": false, + \"visible\": false\n// Hide the main window by default }, // Add the splashscreen window + { +\n\"width\": 400, + \"height\": 200, + \"decorations\": false, + \"url\":\n\"splashscreen.html\", + \"label\": \"splashscreen\" + } ] ``` Now, your main window\nwill be hidden and the splashscreen window will show when your app is launched.\nNext, you'll need a way to close the splashscreen and show the main window when\nyour app is ready. How you do this depends on what you are waiting for before\nclosing the splashscreen. ### Waiting for Webpage If you are waiting for your\nweb code, you'll want to create a `close_splashscreen` [command](command.md).\n```rust title=src-tauri/main.rs use tauri::Manager; // Create the command:\n#[tauri::command] fn close_splashscreen(window: tauri::Window) { // Close\nsplashscreen if let Some(splashscreen) = window.get_window(\"splashscreen\") {\nsplashscreen.close().unwrap(); } // Show main window\nwindow.get_window(\"main\").unwrap().show().unwrap(); } // Register the command:\nfn main() { tauri::Builder::default() // Add this line\n.invoke_handler(tauri::generate_handler![close_splashscreen])\n.run(tauri::generate_context!()) .expect(\"failed to run app\"); } ``` Then, you\ncan call it from your JS: ```js // With the Tauri API npm package: import {\ninvoke } from '@tauri-apps/api/tauri' // With the Tauri global script: const\ninvoke = window.__TAURI__.invoke document.addEventListener('DOMContentLoaded',\n() => { // This will wait for the window to load, but you could // run this\nfunction on whatever trigger you want invoke('close_splashscreen') }) ``` ###\nWaiting for Rust If you are waiting for Rust code to run, put it in the `setup`\nfunction handler so you have access to the `App` instance: ```rust\ntitle=src-tauri/main.rs use tauri::Manager; fn main() {\ntauri::Builder::default() .setup(|app| { let splashscreen_window =\napp.get_window(\"splashscreen\").unwrap(); let main_window =\napp.get_window(\"main\").unwrap(); // we perform the initialization code on a new\ntask so the app doesn't freeze tauri::async_runtime::spawn(async move { //\ninitialize your app here instead of sleeping :) println!(\"Initializing...\");\nstd::thread::sleep(std::time::Duration::from_secs(2)); println!(\"Done\ninitializing.\"); // After it's done, close the splashscreen and display the main\nwindow splashscreen_window.close().unwrap(); main_window.show().unwrap(); });\nOk(()) }) .run(tauri::generate_context!()) .expect(\"failed to run app\"); } ```","url":"https://tauri.studio/docs/guides/splashscreen"},{"id":"prose_docs_guides_system_tray_md","title":"System Tray","area":"guides","section":"guides","headings":[],"subHeadings":["Setup","Creating a system tray","Configuring a system tray context menu","Configure the app system tray","Listening to system tray events","Updating system tray"],"code":["json","rust"],"text":"Native application system tray. ### Setup Configure the `systemTray` object on\n`tauri.conf.json`: ```json { \"tauri\": { \"systemTray\": { \"iconPath\":\n\"icons/icon.png\", \"iconAsTemplate\": true } } } ``` The `iconPath` is pointed to\na PNG file on macOS and Linux, and a `.ico` file must exist for Windows support.\nThe `iconAsTemplate` is a boolean value that determines whether the image\nrepresents a\n[template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc)\nimage on macOS. ### Creating a system tray To create a native system tray,\nimport the `SystemTray` type: ```rust use tauri::SystemTray; ``` Initialize a\nnew tray instance: ```rust let tray = SystemTray::new(); ``` ### Configuring a\nsystem tray context menu Optionally you can add a context menu that is visible\nwhen the tray icon is right clicked. Import the `SystemTrayMenu`,\n`SystemTrayMenuItem` and `CustomMenuItem` types: ```rust use\ntauri::{CustomMenuItem, SystemTrayMenu, SystemTrayMenuItem}; ``` Create the\n`SystemTrayMenu`: ```rust // here `\"quit\".to_string()` defines the menu item id,\nand the second parameter is the menu item label. let quit =\nCustomMenuItem::new(\"quit\".to_string(), \"Quit\"); let hide =\nCustomMenuItem::new(\"hide\".to_string(), \"Hide\"); let tray_menu =\nSystemTrayMenu::new() .add_item(quit)\n.add_native_item(SystemTrayMenuItem::Separator) .add_item(hide); ``` Add the\ntray menu to the `SystemTray` instance: ```rust let tray =\nSystemTray::new().with_menu(tray_menu); ``` ### Configure the app system tray\nThe created `SystemTray` instance can be set using the `system_tray` API on the\n`tauri::Builder` struct: ```rust use tauri::{CustomMenuItem, SystemTray,\nSystemTrayMenu}; fn main() { let tray_menu = SystemTrayMenu::new(); // insert\nthe menu items here let system_tray = SystemTray::new() .with_menu(tray_menu);\ntauri::Builder::default() .system_tray(system_tray)\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ### Listening to system tray events Each `CustomMenuItem`\ntriggers an event when clicked. Also, Tauri emits tray icon click events. Use\nthe `on_system_tray_event` API to handle them: ```rust use\ntauri::{CustomMenuItem, SystemTray, SystemTrayMenu}; use tauri::Manager; fn\nmain() { let tray_menu = SystemTrayMenu::new(); // insert the menu items here\ntauri::Builder::default() .system_tray(SystemTray::new().with_menu(tray_menu))\n.on_system_tray_event(|app, event| match event { SystemTrayEvent::LeftClick {\nposition: _, size: _, .. } => { println!(\"system tray received a left click\"); }\nSystemTrayEvent::RightClick { position: _, size: _, .. } => { println!(\"system\ntray received a right click\"); } SystemTrayEvent::DoubleClick { position: _,\nsize: _, .. } => { println!(\"system tray received a double click\"); }\nSystemTrayEvent::MenuItemClick { id, .. } => { match id.as_str() { \"quit\" => {\nstd::process::exit(0); } \"hide\" => { let window =\napp.get_window(\"main\").unwrap(); window.hide().unwrap(); } _ => {} } } _ => {}\n}) .run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ### Updating system tray The `AppHandle` struct has a\n`tray_handle` method, which returns a handle to the system tray allowing\nupdating tray icon and context menu items: #### Updating context menu items\n```rust use tauri::{CustomMenuItem, SystemTray, SystemTrayMenu}; use\ntauri::Manager; fn main() { let tray_menu = SystemTrayMenu::new(); // insert the\nmenu items here tauri::Builder::default()\n.system_tray(SystemTray::new().with_menu(tray_menu)) .on_system_tray_event(|app,\nevent| match event { SystemTrayEvent::MenuItemClick { id, .. } => { // get a\nhandle to the clicked menu item // note that `tray_handle` can be called\nanywhere, // just get a `AppHandle` instance with `app.handle()` on the setup\nhook // and move it to another function or thread let item_handle =\napp.tray_handle().get_item(&id); match id.as_str() { \"hide\" => { let window =\napp.get_window(\"main\").unwrap(); window.hide().unwrap(); // you can also\n`set_selected`, `set_enabled` and `set_native_image` (macOS only).\nitem_handle.set_title(\"Show\").unwrap(); } _ => {} } } _ => {} })\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` #### Updating tray icon Note that `tauri::Icon` must be a\n`Path` variant on Linux, and `Raw` variant on Windows and macOS. ```rust\napp.tray_handle().set_icon(tauri::Icon::Raw(include_bytes!(\"../path/to/myicon.ico\"))).unwrap();\n```","url":"https://tauri.studio/docs/guides/system-tray"},{"id":"prose_docs_guides_window_customization_md","title":"Window Customization","area":"guides","section":"guides","headings":["Configuration","Creating a Custom Titlebar"],"subHeadings":["CSS","HTML","JS"],"code":["css","html","js"],"text":"` tag: ```html\nminimize [https://api.iconify.design/mdi:window-minimize.svg]\nmaximize [https://api.iconify.design/mdi:window-maximize.svg]\nclose [https://api.iconify.design/mdi:close.svg]\n``` Note that you may need to move the rest of your content down so that the\ntitlebar doesn't cover it. ### JS Finally, you'll need to make the buttons work:\n```js import { appWindow } from '@tauri-apps/api/window' document\n.getElementById('titlebar-minimize') .addEventListener('click', () =>\nappWindow.minimize()) document .getElementById('titlebar-maximize')\n.addEventListener('click', () => appWindow.toggleMaximize()) document\n.getElementById('titlebar-close') .addEventListener('click', () =>\nappWindow.close()) ```","url":"https://tauri.studio/docs/guides/window-customization"},{"id":"prose_docs_testing_webdriver_ci_md","title":"Continuous Integration","area":"testing","section":"webdriver","headings":[],"subHeadings":[],"code":["yaml"],"text":"Utilizing Linux and some programs to create a fake display, it is possible to\nrun [WebDriver] tests with [`tauri-driver`] on your CI. The following example\nwill use the [WebdriverIO] example we [previously built together] and GitHub\nActions. This means the following assumptions: 1. The Tauri application is in\nthe repository root and the binary builds when running `cargo build --release`.\n2. The [WebDriverIO] test runner is in the `webdriver/webdriverio` directory and\nruns when `yarn test` is used in that directory. The following is a commented\nGitHub Actions workflow file at `.github/workflows/webdriver.yml` ```yaml # run\nthis action when the repository is pushed to on: [ push ] # the name of our\nworkflow name: WebDriver jobs: # a single job named test test: # the display\nname the test job name: WebDriverIO Test Runner # we want to run on the latest\nlinux environment runs-on: ubuntu-latest # the steps our job runs **in order**\nsteps: # checkout the code on the workflow runner - uses: actions/checkout@v2 #\ninstall system dependencies that Tauri needs to compile on Linux. # note the\nextra dependencies for `tauri-driver` to run which are `webkit2gtk-driver` and\n`xvfb` - name: Tauri dependencies run: >- sudo apt-get update && sudo apt-get\ninstall -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0\nlibappindicator3-dev webkit2gtk-driver xvfb # install the latest Rust stable -\nname: Rust stable uses: actions-rs/toolchain@v1 with: toolchain: stable # we run\nour rust tests before the webdriver tests to avoid testing a broken application\n- name: Cargo test uses: actions-rs/cargo@v1 with: command: test # build a\nrelease build of our application to be used during our WebdriverIO tests - name:\nCargo build uses: actions-rs/cargo@v1 with: command: build args: --release #\ninstall the latest stable node version at the time of writing - name: Node v16\nuses: actions/setup-node@v2 with: node-version: 16.x # install our Node.js\ndependencies with Yarn - name: Yarn install run: yarn install working-directory:\nwebdriver/webdriverio # install the latest version of `tauri-driver`. # note:\nthe tauri-driver version is independent of any other Tauri versions - name:\nInstall tauri-driver uses: actions-rs/cargo@v1 with: command: install args:\ntauri-driver # run the WebdriverIO test suite. # we run it through `xvfb-run`\n(the dependency we installed earlier) to have a fake # display server which\nallows our application to run headless without any changes to the code - name:\nWebdriverIO run: xvfb-run yarn test working-directory: webdriver/webdriverio ```\n[WebDriver]: https://www.w3.org/TR/webdriver/ [`tauri-driver`]:\nhttps://crates.io/crates/tauri-driver [WebdriverIO]: https://webdriver.io/\n[previously built together]: example/webdriverio","url":"https://tauri.studio/docs/testing/webdriver/ci"},{"id":"prose_docs_testing_webdriver_introduction_md","title":"Introduction","area":"testing","section":"webdriver","headings":["System Dependencies","Example Application"],"subHeadings":["Linux","Windows"],"code":["sh"],"text":"import Alert from '@theme/Alert' Webdriver support for Tauri is still in\npre-alpha. Tooling that is dedicated to it such as [tauri-driver] is still in\nactive development and may change as necessary over time. Additionally, only\nWindows and Linux are currently supported. [WebDriver] is a standardized\ninterface to interact with web documents that is primarily intended for\nautomated testing. Tauri supports the [WebDriver] interface by leveraging the\nnative platform's [WebDriver] server underneath a cross-platform wrapper\n[`tauri-driver`]. ## System Dependencies Install the latest [`tauri-driver`] or\nupdate an existing installation by running: ```sh cargo install tauri-driver ```\nBecause we currently utilize the platform's native [WebDriver] server, there are\nsome requirements for running [`tauri-driver`] on supported platforms. Platform\nsupport is currently limited to Linux and Windows. ### Linux We use\n`WebKitWebDriver` on linux platforms. Check if this binary exists already\n(command `which WebKitWebDriver`) as some distributions bundle it with the\nregular webkit package. Other platforms may have a separate package for them\nsuch as `webkit2gtk-driver` on Debian based distributions. ### Windows Make sure\nto grab the version of [Microsoft Edge Driver] that matches your Windows' Edge\nversion that the application is being built and tested on. On up-to-date Window\ninstalls, this should almost always be the latest stable version. If the two\nversions do not match, you may experience your WebDriver testing suite hanging\nwhile trying to connect. The download contains a binary called\n`msedgedriver.exe`. [`tauri-driver`] looks for that binary in the `$PATH` so\nmake sure it's either available on the path or use the `--native-driver` option\non [`tauri-driver`]. On Windows CI machines, you may want to download this\nautomatically as part of the CI setup process to ensure the Edge and Edge Driver\nversions stay in sync. A guide on how to do this may be added at a later date.\n## Example Application The [next section](example/setup) of the guide will show\nstep-by-step how to create a minimal example application that is tested with\nWebDriver. If you prefer to just see the result of the guide and look over a\nfinished minimal codebase that utilizes it then you can look at\nhttps://github.com/chippers/hello_tauri. That example also comes with a CI\nscript to test with GitHub actions, but you may still be interested in the\n[WebDriver CI](ci) guide as it explains the concept a bit more. [WebDriver]:\nhttps://www.w3.org/TR/webdriver/ [`tauri-driver`]:\nhttps://crates.io/crates/tauri-driver [tauri-driver]:\nhttps://crates.io/crates/tauri-driver [Microsoft Edge Driver]:\nhttps://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/","url":"https://tauri.studio/docs/testing/webdriver/introduction"},{"id":"prose_docs_testing_webdriver_example_selenium_md","title":"Selenium","area":"testing","parentSection":"webdriver","section":"example","headings":["Create a Directory for the Tests","Initializing a Selenium Project","Testing","Running the Test Suite"],"subHeadings":[],"code":["sh",null,"text"],"text":"import Alert from '@theme/Alert' import Tabs from '@theme/Tabs' import TabItem\nfrom '@theme/TabItem' This [Selenium] guide expects you to have already gone\nthrough the [example Application setup] in order to follow step-by-step. The\ngeneral information may still be useful otherwise. This WebDriver testing\nexample will use [Selenium] and a popular Node.js testing suite. It is expected\nto already have Node.js installed, along with `npm` or `yarn` although the\n[finished example project] uses `yarn`. ## Create a Directory for the Tests\nLet's start off by creating a space in our project to write these tests. We are\ngoing to be using a nested directory for this example project as we will later\nalso go over other frameworks, but typically you will only need to use one.\nCreate the directory we will use with `mkdir -p webdriver/selenium`. The rest of\nthis guide will assume you are inside the `webdriver/selenium` directory. ##\nInitializing a Selenium Project We will be using a pre-existing `package.json`\nto bootstrap this test suite because we have already chosen specific\ndependencies to use and want to showcase a simple working solution. The bottom\nof this section has a collapsed guide on how to set it up from scratch.\n`package.json`: ```json { \"name\": \"selenium\", \"version\": \"1.0.0\", \"private\":\ntrue, \"scripts\": { \"test\": \"mocha\" }, \"dependencies\": { \"chai\": \"^4.3.4\",\n\"mocha\": \"^9.0.3\", \"selenium-webdriver\": \"^4.0.0-beta.4\" } } ``` We have a\nscript which runs [Mocha] as a test framework exposed as the `test` command. We\nalso have various dependencies that we will be using to run the tests. [Mocha]\nas the testing framework, [Chai] as the assertion library, and\n[`selenium-webdriver`] which is the Node.js [Selenium] package. Click me if you\nwant to see how to set a project up from scratch If you wanted to install the\ndependencies from scratch, just run the following command. ```sh npm install\nmocha chai selenium-webdriver ``` ```sh yarn add mocha chai selenium-webdriver\n``` I suggest also adding a `\"test\": \"mocha\"` item in the `package.json`\n`\"scripts\"` key so that running mocha can be called simply with ```sh npm test\n``` ```sh yarn test ``` ## Testing Unlike the [WebdriverIO Test\nSuite](webdriverio#config), Selenium does not come out of the box with a Test\nSuite and leaves it up to the developer to build those out. We chose [Mocha]\nwhich is pretty neutral, and not related to WebDrivers at all, so our script\nwill need to do a bit of work to set up everything for us in the right order.\n[Mocha] expects a testing file at `test/test.js` by default, so let's create\nthat file now. `test/test.js`: ```js const os = require(\"os\"); const path =\nrequire(\"path\"); const { expect } = require(\"chai\"); const { spawn, spawnSync }\n= require(\"child_process\"); const { Builder, By, Capabilities } =\nrequire(\"selenium-webdriver\"); // create the path to the expected application\nbinary const application = path.resolve( __dirname, \"..\", \"..\", \"..\", \"target\",\n\"release\", \"hello-tauri-webdriver\" ); // keep track of the webdriver instance we\ncreate let driver; // keep track of the tauri-driver process we start let\ntauriDriver; before(async function() { // set timeout to 2 minutes to allow the\nprogram to build if it needs to this.timeout(120000) // ensure the program has\nbeen built spawnSync(\"cargo\", [\"build\", \"--release\"]); // start tauri-driver\ntauriDriver = spawn( path.resolve(os.homedir(), \".cargo\", \"bin\",\n\"tauri-driver\"), [], { stdio: [null, process.stdout, process.stderr] } ); const\ncapabilities = new Capabilities(); capabilities.set(\"tauri:options\", {\napplication }); capabilities.setBrowserName(\"wry\"); // start the webdriver\nclient driver = await new Builder() .withCapabilities(capabilities)\n.usingServer(\"http://localhost:4444/\") .build(); }); after(async function() { //\nstop the webdriver session await driver.quit(); // kill the tauri-driver process\ntauriDriver.kill(); }); describe(\"Hello Tauri\", () => { it(\"should be cordial\",\nasync () => { const text = await driver.findElement(By.css(\"body >\nh1\")).getText(); expect(text).to.match(/^[hH]ello/); }); it(\"should be excited\",\nasync () => { const text = await driver.findElement(By.css(\"body >\nh1\")).getText(); expect(text).to.match(/!$/); }); it(\"should be easy on the\neyes\", async () => { // selenium returns color css values as rgb(r, g, b) const\ntext = await driver.findElement(By.css(\"body\")).getCssValue(\"background-color\");\nconst rgb = text.match(/^rgb\\((?\\d+), (?\\d+), (?\\d+)\\)$/).groups;\nexpect(rgb).to.have.all.keys('r','g','b'); const luma = 0.2126 * rgb.r + 0.7152\n* rgb.g + 0.0722 * rgb.b ; expect(luma).to.be.lessThan(100) }); }); ``` If you\nare familiar with JS testing frameworks, `describe`, `it`, and `expect` should\nlook familiar. We also have semi-complex `before()` and `after()` callbacks to\nsetup and teardown mocha. Lines that are not the tests themselves have comments\nexplaining what the setup and teardown code is doing. If you were familiar with\nthe Spec file from the [WebdriverIO example](webdriverio#spec), you will notice\na lot more code that isn't tests, as we have to set up a few more WebDriver\nrelated items. ## Running the Test Suite Now that we are all set up with our\ndependencies and our test script, lets run it! ```sh npm test ``` ```sh yarn\ntest ``` We should see output the following output: ```text ➜ selenium\ngit:(main) ✗ yarn test yarn run v1.22.11 $ mocha Hello Tauri ✔ should be cordial\n(120ms) ✔ should be excited ✔ should be easy on the eyes 3 passing (588ms) Done\nin 0.93s. ``` We can see that our `Hello Tauri` sweet we created with `decribe`\nhad all 3 items we created with `it` pass their tests! With [Selenium] and some\nhooking up to a test suite, we just enabled e2e testing without modifying our\nTauri application at all! [Selenium]: https://selenium.dev/ [finished example\nproject]: https://github.com/chippers/hello_tauri [example Application setup]:\nsetup [Mocha]: https://mochajs.org/ [Chai]: https://www.chaijs.com/\n[`selenium-webdriver`]: https://www.npmjs.com/package/selenium-webdriver","url":"https://tauri.studio/docs/testing/webdriver/example/selenium"},{"id":"prose_docs_testing_webdriver_example_setup_md","title":"Setup Example","area":"testing","parentSection":"webdriver","section":"example","headings":["Initializing a Cargo Project","Creating a Minimal Frontend","Adding Tauri to the Cargo Project","Tauri Configuration","Running the Example Application"],"subHeadings":[],"code":["html","toml","rust","json"],"text":"HELLO, TAURI!","url":"https://tauri.studio/docs/testing/webdriver/example/setup"},{"id":"prose_docs_testing_webdriver_example_webdriverio_md","title":"WebdriverIO","area":"testing","parentSection":"webdriver","section":"example","headings":["Create a Directory for the Tests","Initializing a WebdriverIO Project","Config","Spec","Running the Test Suite"],"subHeadings":[],"code":["sh","text"],"text":"import Alert from '@theme/Alert' import Tabs from '@theme/Tabs' import TabItem\nfrom '@theme/TabItem' This [WebdriverIO] guide expects you to have already gone\nthrough the [example Application setup] in order to follow step-by-step. The\ngeneral information may still be useful otherwise. This WebDriver testing\nexample will use [WebdriverIO] and its testing suite. It is expected to already\nhave Node.js installed, along with `npm` or `yarn` although the [finished\nexample project] uses `yarn`. ## Create a Directory for the Tests Let's start\noff by creating a space in our project to write these tests. We are going to be\nusing a nested directory for this example project as we will later also go over\nother frameworks, but typically you will only need to use one. Create the\ndirectory we will use with `mkdir -p webdriver/webdriverio`. The rest of this\nguide will assume you are inside the `webdriver/webdriverio` directory. ##\nInitializing a WebdriverIO Project We will be using a pre-existing\n`package.json` to bootstrap this test suite because we have already chosen\nspecific [WebdriverIO] config options and want to showcase a simple working\nsolution. The bottom of this section has a collapsed guide on how to set it up\nfrom scratch. `package.json`: ```json { \"name\": \"webdriverio\", \"version\":\n\"1.0.0\", \"private\": true, \"scripts\": { \"test\": \"wdio run wdio.conf.js\" },\n\"dependencies\": { \"@wdio/cli\": \"^7.9.1\" }, \"devDependencies\": {\n\"@wdio/local-runner\": \"^7.9.1\", \"@wdio/mocha-framework\": \"^7.9.1\",\n\"@wdio/spec-reporter\": \"^7.9.0\" } } ``` We have a script which runs a\n[WebdriverIO] config as a test suite exposed as the `test` command. We also have\nvarious dependencies that were added by the `@wdio/cli` command when we first\nset it up. In short, these dependencies are for the most simple setup using a\nlocal WebDriver runner, [Mocha] as the test framework, and a simple Spec\nReporter. Click me if you want to see how to set a project up from scratch The\nCLI is interactive, and you may choose the tools to work with yourself. Note\nthat you will likely diverge from the rest of the guide, and need to set up the\ndifferences yourself. Let's add the [WebdriverIO] CLI to this npm project. ```sh\nnpm install @wdio/cli ``` ```sh yarn add @wdio/cli ``` To then run the\ninteractive config command to set up a [WebdriverIO] test suite, you can then\nrun: ```sh npx wdio config ``` ```sh yarn wdio config ``` ## Config You may have\nnoticed that the `test` script in our `package.json` mentions a file\n`wdio.conf.js`. That's the [WebdriverIO] config file which controls most aspects\nof our testing suite. `wdio.conf.js`: ```js const os = require(\"os\"); const path\n= require(\"path\"); const { spawn, spawnSync } = require(\"child_process\"); //\nkeep track of the `tauri-driver` child process let tauriDriver; exports.config =\n{ specs: [\"./test/specs/**/*.js\"], maxInstances: 1, capabilities: [ {\nmaxInstances: 1, \"tauri:options\": { application:\n\"../../target/release/hello-tauri-webdriver\", }, }, ], reporters: [\"spec\"],\nframework: \"mocha\", mochaOpts: { ui: \"bdd\", timeout: 60000, }, // ensure the\nrust project is built since we expect this binary to exist for the webdriver\nsessions onPrepare: () => spawnSync(\"cargo\", [\"build\", \"--release\"]), // ensure\nwe are running `tauri-driver` before the session starts so that we can proxy the\nwebdriver requests beforeSession: () => (tauriDriver = spawn(\npath.resolve(os.homedir(), \".cargo\", \"bin\", \"tauri-driver\"), [], { stdio: [null,\nprocess.stdout, process.stderr] } )), // clean up the `tauri-driver` process we\nspawned at the start of the session afterSession: () => tauriDriver.kill(), };\n``` If you are interested in the properties on `exports.config` object, then I\n[suggest reading the documentation] for it. For non-WDIO specific items, there\nare comments explaining why we are running commands in `onPrepare`,\n`beforeSession`, and `afterSession`. We also have our specs set to\n`\"./test/specs/**/*.js\"`, so let's create a spec now. ## Spec A spec contains\nthe code that is testing your actual application. The test runner will load\nthese specs and automatically run them as it sees fit. Let's create our spec now\nin the directory we specified. `test/specs/example.e2e.js`: ```js // calculates\nthe luma from a hex color `#abcdef` function luma(hex) { if\n(hex.startsWith(\"#\")) { hex = hex.substring(1); } const rgb = parseInt(hex, 16);\nconst r = (rgb >> 16) & 0xff; const g = (rgb >> 8) & 0xff; const b = (rgb >> 0)\n& 0xff; return 0.2126 * r + 0.7152 * g + 0.0722 * b; } describe(\"Hello Tauri\",\n() => { it(\"should be cordial\", async () => { const header = await $(\"body >\nh1\"); const text = await header.getText(); expect(text).toMatch(/^[hH]ello/);\n}); it(\"should be excited\", async () => { const header = await $(\"body > h1\");\nconst text = await header.getText(); expect(text).toMatch(/!$/); }); it(\"should\nbe easy on the eyes\", async () => { const body = await $(\"body\"); const\nbackgroundColor = await body.getCSSProperty(\"background-color\");\nexpect(luma(backgroundColor.parsed.hex)).toBeLessThan(100); }); }); ``` The\n`luma` function on top is just a helper function for one of our tests and is not\nrelated to the actual testing of the application. If you are familiar with other\ntesting frameworks, you may notice similar functions being exposed that are used\nsuch as `describe`, `it`, and `expect`. The other APIs, such as items like `$`\nand the methods it exposes is covered by the [WebdriverIO API\ndocs](https://webdriver.io/docs/api). ## Running the Test Suite Now that we are\nall set up with a config and a spec, let's run it! ```sh npm test ``` ```sh yarn\ntest ``` We should see output the following output: ```text ➜ webdriverio\ngit:(main) ✗ yarn test yarn run v1.22.11 $ wdio run wdio.conf.js Execution of 1\nworkers started at 2021-08-17T08:06:10.279Z [0-0] RUNNING in undefined -\n/test/specs/example.e2e.js [0-0] PASSED in undefined -\n/test/specs/example.e2e.js \"spec\" Reporter:\n------------------------------------------------------------------ [wry 0.12.1\nlinux #0-0] Running: wry (v0.12.1) on linux [wry 0.12.1 linux #0-0] Session ID:\n81e0107b-4d38-4eed-9b10-ee80ca47bb83 [wry 0.12.1 linux #0-0] [wry 0.12.1 linux\n#0-0] » /test/specs/example.e2e.js [wry 0.12.1 linux #0-0] Hello Tauri [wry\n0.12.1 linux #0-0] ✓ should be cordial [wry 0.12.1 linux #0-0] ✓ should be\nexcited [wry 0.12.1 linux #0-0] ✓ should be easy on the eyes [wry 0.12.1 linux\n#0-0] [wry 0.12.1 linux #0-0] 3 passing (244ms) Spec Files: 1 passed, 1 total\n(100% completed) in 00:00:01 Done in 1.98s. ``` We see the Spec Reporter tell us\nthat all 3 tests from the `test/specs/example.e2e.js` file, along with the final\nreport `Spec Files: 1 passed, 1 total (100% completed) in 00:00:01`. Using the\n[WebdriverIO] test suite, we just easily enabled e2e testing for our Tauri\napplication from just a few lines of configuration and a single command to run\nit! Even better, we didn't have to modify the application at all. [WebdriverIO]:\nhttps://webdriver.io/ [finished example project]:\nhttps://github.com/chippers/hello_tauri [example Application setup]: setup\n[Mocha]: https://mochajs.org/ [suggest reading the documentation]:\nhttps://webdriver.io/docs/configurationfile","url":"https://tauri.studio/docs/testing/webdriver/example/webdriverio"}] \ No newline at end of file +[{"id":"prose_docs_architecture_md","title":"The Tauri Architecture","headings":["What does the Release flow look like"],"subHeadings":[],"code":[null],"text":"# The Tauri Architecture ## Introduction Tauri is a polyglot and generic toolkit\nthat is very composable and allows engineers to make a wide variety of\napplications. It is used for building applications for Desktop Computers using a\ncombination of Rust tools and HTML rendered in a Webview. Apps built with Tauri\ncan ship with any number of pieces of an optional JS API / Rust API so that\nwebviews can control the system via message passing. In fact, developers can\nextend the default API with their own functionality and bridge the Webview and\nRust-based backend easily. Tauri apps can have custom menus and have tray-type\ninterfaces. They can be updated, and are managed by the user's operating system\nas expected. They are very small, because they use the OS's webview. They do not\nship a runtime, since the final binary is compiled from Rust. This makes the\nreversing of Tauri apps not a trivial task. ## What Tauri is NOT - Tauri is not\na lightweight kernel wrapper...instead it directly uses [WRY](#wry) and\n[TAO](#tao) to do the heavy-lifting in making system calls to the OS. - Tauri is\nnot a VM or virtualized environment...instead it is an application toolkit that\nallows making Webview OS applications. ## Major Components The following section\nbriefly describes the roles of the various parts of Tauri. ### Tauri Core\n[STABLE RUST] ####\n[tauri](https://github.com/tauri-apps/tauri/tree/dev/core/tauri) This is the\nmajor crate that holds everything together. It brings the runtimes, macros,\nutilities and API into one final product. It reads the `tauri.conf.json` file at\ncompile time in order to bring in features and undertake actual configuration of\nthe app (and even the `Cargo.toml` file in the project's folder). It handles\nscript injection (for polyfills / prototype revision) at runtime, hosts the API\nfor systems interaction, and even manages updating. ####\n[tauri-build](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-build)\nApply the macros at build-time in order to rig some special features needed by\n`cargo`. ####\n[tauri-codegen](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-codegen)\n- Embed, hash, and compress assets, including icons for the app as well as the\nsystem-tray. - Parse `tauri.conf.json` at compile time and generate the Config\nstruct. ####\n[tauri-macros](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-macros)\nCreate macros for the context, handler, and commands by leveraging the\n`tauri-codegen` crate. ####\n[tauri-runtime](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime)\nThis is the glue layer between tauri itself and lower level webview libraries.\n####\n[tauri-runtime-wry](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime-wry)\nThis crate opens up direct systems-level interactions specifically for WRY, such\nas printing, monitor detection, and other windowing related tasks.\n`tauri-runtime` implementation for WRY. ####\n[tauri-utils](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-utils)\nThis is common code that is reused in many places and offers useful utilities\nlike parsing configuration files, detecting platform triples, injecting the CSP,\nand managing assets. ### Tauri Tooling ####\n[api](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) [TS -> JS] A\ntypescript library that creates `cjs` and `esm` Javascript endpoints for you to\nimport into your Frontend framework so that the Webview can call and listen to\nbackend activity. We also ship the pure typescript, because for some frameworks\nthis is more optimal. It uses the message passing of webviews to their hosts.\n#### [bundler](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler)\n[RUST / SHELL] The bundler is a library that builds a Tauri App for the platform\ntriple it detects / is told. At the moment it currently supports macOS, Windows\nand Linux - but in the near future will support mobile platforms as well. May be\nused outside of Tauri projects. ####\n[cli.js](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli.js) [JS]\nWritten in Typescript and packaged such that it can be used with `npm`, `pnpm`,\nand `yarn`, this library provides a node.js runner for common tasks when using\nTauri, like `yarn tauri dev`. For the most part it is a wrapper around\n[cli.rs](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli). ####\n[cli.rs](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) [RUST] This\nrust executable provides the full interface to all of the required activities\nfor which the CLI is required. It will run on macOS, Windows, and Linux. ####\n[create-tauri-app](https://github.com/tauri-apps/tauri/tree/dev/tooling/create-tauri-app)\n[JS] This is a toolkit that will enable engineering teams to rapidly scaffold\nout a new tauri-apps project using the frontend framework of their choice (as\nlong as it has been configured). # External Crates The Tauri-Apps organisation\nmaintains two \"upstream\" crates from Tauri, namely TAO for creating and managing\napplication windows, and WRY for interfacing with the Webview that lives within\nthe window. ## [TAO](https://github.com/tauri-apps/tao) Cross-platform\napplication window creation library in Rust that supports all major platforms\nlike Windows, macOS, Linux, iOS and Android. Written in Rust, it is a fork of\n[winit](https://github.com/rust-windowing/winit) that we have extended for our\nown needs like menu bar and system tray. ##\n[WRY](https://github.com/tauri-apps/wry) WRY is a cross-platform WebView\nrendering library in Rust that supports all major desktop platforms like\nWindows, macOS, and Linux. Tauri uses WRY as the abstract layer responsible to\ndetermine which webview is used (and how interactions are made). ##\n[tauri-hotkey-rs](https://github.com/tauri-apps/tauri-hotkey-rs) We needed to\nfix hotkey to work on all platforms, because upstream was not being responsive.\n# Additional tooling ##\n[binary-releases](https://github.com/tauri-apps/binary-releases) This is the\ndelivery mechanism for tauri prebuilt binaries: currently the cli.rs (used by\ncli.js) and rustup binaries (used by the deps install command of cli.js). These\nartifacts are automatically created on release. ##\n[tauri-action](https://github.com/tauri-apps/tauri-action) This is a github\nworkflow that builds tauri binaries for all platforms. It is not the fastest out\nthere, but it gets the job done and is highly configurable. Even allowing you to\ncreate a (very basic) tauri app even if tauri is not setup. ##\n[create-pull-request](https://github.com/tauri-apps/create-pull-request) Because\nthis is a very risky (potentially destructive) github action, we forked it in\norder to have strong guarantees that the code we think is running is actually\nthe code that is running. ##\n[vue-cli-plugin-tauri](https://github.com/tauri-apps/vue-cli-plugin-tauri) This\nplugin allows you to very quickly install tauri in a vue-cli project. ##\n[tauri-vscode](https://github.com/tauri-apps/tauri-vscode) This project enhances\nthe VS Code interface with several nice-to-have features. # Tauri Plugins\n[documentation](https://tauri.studio/en/docs/guides/plugin) Generally speaking,\nplugins are authored by third parties (even though there may be official,\nsupported plugins). A plugin generally does 3 things: 1. It provides rust code\nto do \"something\". 2. It provides interface glue to make it easy to integrate\ninto an app. 3. It provides a JS API for interfacing with the rust code. Here\nare several examples of Tauri Plugins: -\nhttps://github.com/tauri-apps/tauri-plugin-sql -\nhttps://github.com/tauri-apps/tauri-plugin-stronghold -\nhttps://github.com/tauri-apps/tauri-plugin-authenticator # Workflows ## What\ndoes the Development flow look like? A developer must first install the\nprerequisite toolchains for creating a Tauri app. At the very least this will\nentail installing rust & cargo, and most likely also a modern version of node.js\nand potentially another package manager. Some platforms may also require other\ntooling and libraries, but this has been documented carefully in the respective\nplatform docs. Because of the many ways to build front-ends, we will stick with\na common node.js based approach for development. (Note: Tauri does not by\ndefault ship a node.js runtime.) The easiest way to do this is to run the\nfollowing: ``` npx create-tauri-app ``` Which will ask you a bunch of questions\nabout the framework you want to install and then create everything you need in a\nsingle folder - some via the placement of template files and some through normal\ninstallation procedures of your framework. > If you don't use this process, you\nwill have to manually install the tauri cli, initialise tauri and manually\nconfigure the `tauri.conf.json` file. Once everything is installed, you can run:\n``` yarn tauri dev -or- npm run tauri dev ``` This will do several things: 1.\nstart the JS Framework devserver 2. begin the long process of downloading and\ncompiling the rust libraries 3. open an application window with devtools enabled\n4. keep a long-lived console alive If you change your HTML/CSS/TS/JS, your\nframework devserver should give you its best shot at instant hot module\nreloading and you will see the changes instantly. If you modify your rust code\nor anything in the Cargo.toml, the window will close while rust recompiles. When\nfinished it will reload. If you need to get deeper insight into your current\nproject, or triage requires investigation of installed components, just run: ```\nyarn tauri info ``` ## What does the Release flow look like? The release flow\nbegins with proper configuration in the `tauri.conf.json` file. In this file,\nthe developer can configure not only the basic behaviour of the application\n(like window size and decoration), they can also provide settings for signing\nand updating. Depending upon the operating system that the developer (or CI) is\nbuilding the application on, there will be an app built for them for that\nsystem. (Cross compilation is not currently available, however there is an\nofficial [GitHub Action](https://github.com/tauri-apps/tauri-action) that can be\nused to build for all platforms.) To kick off this process, just: ``` yarn tauri\nbuild ``` After some time, the process will end and you can see the results in\nthe `./src-tauri/target/release` folder. ## What does the End-User flow look\nlike? End users will be provided with binaries in ways that are appropriate for\ntheir systems. Whether macOS, Linux, or Windows, direct download or store\ninstallations - they will be able to follow procedures for installing and\nremoving that they are used to. ## What does the Updating flow look like? When a\nnew version is ready, the developer publishes the new signed artifacts to a\nserver (that they have configured within `tauri.conf.json`). The application can\npoll this server to see if there is a new release. When there is a new release,\nthe user is prompted to update. The application update is downloaded, verified\n(checksum & signature), updated, closed, and restarted. ## License Tauri itself\nis licensed under MIT or Apache-2.0. If you repackage it and modify any source\ncode, it is your responsibility to verify that you are complying with all\nupstream licenses. Tauri is provided AS-IS with no explicit claim for\nsuitability for any purpose. Here you may peruse our [Software Bill of\nMaterials](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri).","url":"https://tauri.studio/docs/architecture"},{"id":"prose_docs_faq_md","title":"Frequently Asked Questions","headings":[],"subHeadings":[],"code":[null],"text":"# error: could not find native static libraryWebView2LoaderStatic, perhaps an -L\nflag is missing? The WebView2 crate build pipeline requires `NuGet` to have a\n`PackageSource` to install the `Microsoft.Web.WebView2` package. If you never\nused `NuGet` before, you might need to create a file named `NuGet.Config` on\n`%APPDATA%/NuGet` folder, with the following contents: ``` ``` This\nconfiguration enables the default `NuGet` registry.","url":"https://tauri.studio/docs/faq"},{"id":"prose_docs_about_architecture_md","title":"The Tauri Architecture","area":"about","section":"about","headings":["What does the Release flow look like"],"subHeadings":[],"code":[null],"text":"# The Tauri Architecture ## Introduction Tauri is a polyglot and generic toolkit\nthat is very composable and allows engineers to make a wide variety of\napplications. It is used for building applications for Desktop Computers using a\ncombination of Rust tools and HTML rendered in a Webview. Apps built with Tauri\ncan ship with any number of pieces of an optional JS API / Rust API so that\nwebviews can control the system via message passing. In fact, developers can\nextend the default API with their own functionality and bridge the Webview and\nRust-based backend easily. Tauri apps can have custom menus and have tray-type\ninterfaces. They can be updated, and are managed by the user's operating system\nas expected. They are very small, because they use the OS's webview. They do not\nship a runtime, since the final binary is compiled from Rust. This makes the\nreversing of Tauri apps not a trivial task. ## What Tauri is NOT - Tauri is not\na lightweight kernel wrapper...instead it directly uses [WRY](#wry) and\n[TAO](#tao) to do the heavy-lifting in making system calls to the OS. - Tauri is\nnot a VM or virtualized environment...instead it is an application toolkit that\nallows making Webview OS applications. ## Major Components The following section\nbriefly describes the roles of the various parts of Tauri. ### Tauri Core\n[STABLE RUST] ####\n[tauri](https://github.com/tauri-apps/tauri/tree/dev/core/tauri) This is the\nmajor crate that holds everything together. It brings the runtimes, macros,\nutilities and API into one final product. It reads the `tauri.conf.json` file at\ncompile time in order to bring in features and undertake actual configuration of\nthe app (and even the `Cargo.toml` file in the project's folder). It handles\nscript injection (for polyfills / prototype revision) at runtime, hosts the API\nfor systems interaction, and even manages updating. ####\n[tauri-build](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-build)\nApply the macros at build-time in order to rig some special features needed by\n`cargo`. ####\n[tauri-codegen](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-codegen)\n- Embed, hash, and compress assets, including icons for the app as well as the\nsystem-tray. - Parse `tauri.conf.json` at compile time and generate the Config\nstruct. ####\n[tauri-macros](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-macros)\nCreate macros for the context, handler, and commands by leveraging the\n`tauri-codegen` crate. ####\n[tauri-runtime](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime)\nThis is the glue layer between tauri itself and lower level webview libraries.\n####\n[tauri-runtime-wry](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime-wry)\nThis crate opens up direct systems-level interactions specifically for WRY, such\nas printing, monitor detection, and other windowing related tasks.\n`tauri-runtime` implementation for WRY. ####\n[tauri-utils](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-utils)\nThis is common code that is reused in many places and offers useful utilities\nlike parsing configuration files, detecting platform triples, injecting the CSP,\nand managing assets. ### Tauri Tooling ####\n[api](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) [TS -> JS] A\ntypescript library that creates `cjs` and `esm` Javascript endpoints for you to\nimport into your Frontend framework so that the Webview can call and listen to\nbackend activity. We also ship the pure typescript, because for some frameworks\nthis is more optimal. It uses the message passing of webviews to their hosts.\n#### [bundler](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler)\n[RUST / SHELL] The bundler is a library that builds a Tauri App for the platform\ntriple it detects / is told. At the moment it currently supports macOS, Windows\nand Linux - but in the near future will support mobile platforms as well. May be\nused outside of Tauri projects. ####\n[cli.js](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli.js) [JS]\nWritten in Typescript and packaged such that it can be used with `npm`, `pnpm`,\nand `yarn`, this library provides a node.js runner for common tasks when using\nTauri, like `yarn tauri dev`. For the most part it is a wrapper around\n[cli.rs](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli). ####\n[cli.rs](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) [RUST] This\nrust executable provides the full interface to all of the required activities\nfor which the CLI is required. It will run on macOS, Windows, and Linux. ####\n[create-tauri-app](https://github.com/tauri-apps/tauri/tree/dev/tooling/create-tauri-app)\n[JS] This is a toolkit that will enable engineering teams to rapidly scaffold\nout a new tauri-apps project using the frontend framework of their choice (as\nlong as it has been configured). # External Crates The Tauri-Apps organisation\nmaintains two \"upstream\" crates from Tauri, namely TAO for creating and managing\napplication windows, and WRY for interfacing with the Webview that lives within\nthe window. ## [TAO](https://github.com/tauri-apps/tao) Cross-platform\napplication window creation library in Rust that supports all major platforms\nlike Windows, macOS, Linux, iOS and Android. Written in Rust, it is a fork of\n[winit](https://github.com/rust-windowing/winit) that we have extended for our\nown needs like menu bar and system tray. ##\n[WRY](https://github.com/tauri-apps/wry) WRY is a cross-platform WebView\nrendering library in Rust that supports all major desktop platforms like\nWindows, macOS, and Linux. Tauri uses WRY as the abstract layer responsible to\ndetermine which webview is used (and how interactions are made). ##\n[tauri-hotkey-rs](https://github.com/tauri-apps/tauri-hotkey-rs) We needed to\nfix hotkey to work on all platforms, because upstream was not being responsive.\n# Additional tooling ##\n[binary-releases](https://github.com/tauri-apps/binary-releases) This is the\ndelivery mechanism for tauri prebuilt binaries: currently the cli.rs (used by\ncli.js) and rustup binaries (used by the deps install command of cli.js). These\nartifacts are automatically created on release. ##\n[tauri-action](https://github.com/tauri-apps/tauri-action) This is a github\nworkflow that builds tauri binaries for all platforms. It is not the fastest out\nthere, but it gets the job done and is highly configurable. Even allowing you to\ncreate a (very basic) tauri app even if tauri is not setup. ##\n[create-pull-request](https://github.com/tauri-apps/create-pull-request) Because\nthis is a very risky (potentially destructive) github action, we forked it in\norder to have strong guarantees that the code we think is running is actually\nthe code that is running. ##\n[vue-cli-plugin-tauri](https://github.com/tauri-apps/vue-cli-plugin-tauri) This\nplugin allows you to very quickly install tauri in a vue-cli project. ##\n[tauri-vscode](https://github.com/tauri-apps/tauri-vscode) This project enhances\nthe VS Code interface with several nice-to-have features. # Tauri Plugins\n[documentation](https://tauri.studio/en/docs/guides/plugin) Generally speaking,\nplugins are authored by third parties (even though there may be official,\nsupported plugins). A plugin generally does 3 things: 1. It provides rust code\nto do \"something\". 2. It provides interface glue to make it easy to integrate\ninto an app. 3. It provides a JS API for interfacing with the rust code. Here\nare several examples of Tauri Plugins: -\nhttps://github.com/tauri-apps/tauri-plugin-sql -\nhttps://github.com/tauri-apps/tauri-plugin-stronghold -\nhttps://github.com/tauri-apps/tauri-plugin-authenticator # Workflows ## What\ndoes the Development flow look like? A developer must first install the\nprerequisite toolchains for creating a Tauri app. At the very least this will\nentail installing rust & cargo, and most likely also a modern version of node.js\nand potentially another package manager. Some platforms may also require other\ntooling and libraries, but this has been documented carefully in the respective\nplatform docs. Because of the many ways to build front-ends, we will stick with\na common node.js based approach for development. (Note: Tauri does not by\ndefault ship a node.js runtime.) The easiest way to do this is to run the\nfollowing: ``` npx create-tauri-app ``` Which will ask you a bunch of questions\nabout the framework you want to install and then create everything you need in a\nsingle folder - some via the placement of template files and some through normal\ninstallation procedures of your framework. > If you don't use this process, you\nwill have to manually install the tauri cli, initialise tauri and manually\nconfigure the `tauri.conf.json` file. Once everything is installed, you can run:\n``` yarn tauri dev -or- npm run tauri dev ``` This will do several things: 1.\nstart the JS Framework devserver 2. begin the long process of downloading and\ncompiling the rust libraries 3. open an application window with devtools enabled\n4. keep a long-lived console alive If you change your HTML/CSS/TS/JS, your\nframework devserver should give you its best shot at instant hot module\nreloading and you will see the changes instantly. If you modify your rust code\nor anything in the Cargo.toml, the window will close while rust recompiles. When\nfinished it will reload. If you need to get deeper insight into your current\nproject, or triage requires investigation of installed components, just run: ```\nyarn tauri info ``` ## What does the Release flow look like? The release flow\nbegins with proper configuration in the `tauri.conf.json` file. In this file,\nthe developer can configure not only the basic behaviour of the application\n(like window size and decoration), they can also provide settings for signing\nand updating. Depending upon the operating system that the developer (or CI) is\nbuilding the application on, there will be an app built for them for that\nsystem. (Cross compilation is not currently available, however there is an\nofficial [GitHub Action](https://github.com/tauri-apps/tauri-action) that can be\nused to build for all platforms.) To kick off this process, just: ``` yarn tauri\nbuild ``` After some time, the process will end and you can see the results in\nthe `./src-tauri/target/release` folder. ## What does the End-User flow look\nlike? End users will be provided with binaries in ways that are appropriate for\ntheir systems. Whether macOS, Linux, or Windows, direct download or store\ninstallations - they will be able to follow procedures for installing and\nremoving that they are used to. ## What does the Updating flow look like? When a\nnew version is ready, the developer publishes the new signed artifacts to a\nserver (that they have configured within `tauri.conf.json`). The application can\npoll this server to see if there is a new release. When there is a new release,\nthe user is prompted to update. The application update is downloaded, verified\n(checksum & signature), updated, closed, and restarted. ## License Tauri itself\nis licensed under MIT or Apache-2.0. If you repackage it and modify any source\ncode, it is your responsibility to verify that you are complying with all\nupstream licenses. Tauri is provided AS-IS with no explicit claim for\nsuitability for any purpose. Here you may peruse our [Software Bill of\nMaterials](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri).","url":"https://tauri.studio/docs/about/architecture"},{"id":"prose_docs_about_book_md","title":"Get the book","area":"about","section":"about","headings":["Outline","Errata"],"subHeadings":["tl","Introduction","About the Topic","What you will learn","Stuff you","Chapter 1 ","Chapter 2 ","Chapter 3 ","Chapter 4 ","Chapter 5 "],"code":[null],"text":"import useBaseUrl from '@docusaurus/useBaseUrl'\nTauri - From Theory to Practice [{useBaseUrl('img/bookCover.png')}]\nTauri: From Theory to Practice\nArchitecting Next-Gen Native-Apps for all Platforms [v1:Rust Edition]\nAuthors: [Daniel Thompson-Yvetot, Lucas Fernandes Gonçalves Nogueira]\nPublisher: TBD\nRelease: late 2020\n### tl;dr; Visit https://opencollective.com/tauri and preorder your copy of the\nbook today. Your donation will support the ongoing development of Tauri, and you\nwill receive advance digital PDF's for your review as chapters are completed.\nThe final book will ship concurrently with the release of 1.0.0 stable. If you\ndonate 10 USD / month to Tauri, you will get the advance PDF versions as soon as\nthey are released. If you just want to donate once: 15 USD for PDF and e-book,\n30 USD for print version and PDF, 40 USD for all three. All tutorial\nsubscription tiers receive the rolling PDF free of additional charge. ###\nIntroduction In 2020, the manufacture of native-apps has become easier and more\naccessible than ever before. All the same, beginners and seasoned developers\nalike are confronted with tough choices in a rapidly changing landscape of\nsecurity and privacy. This is especially true in the semi-trusted environment of\nuser devices. Tauri takes the guesswork out of the equation, as it was designed\nfrom the ground up to embrace new paradigms of secure development and creative\nflexibility that leverage the language features of Rust and lets you build an\napp using any frontend framework you like. Find out how you can design, build,\naudit and deploy tiny, fast, robust, and secure native applications for the\nmajor Desktop and Mobile platforms, all from the exact same codebase and in\nrecord time - without even needing to know the Rust programming language.\nAuthors Daniel and Lucas, the architects behind Tauri take you on a journey from\ntheory to execution, during which you will learn why Tauri was built and how it\nworks under the hood. Together with guest personalities that specialize in Open\nSource, DevOps, Security and Enterprise Architecture, this book also presents\ndiscourse-formatted philosophical discussions and open-source sustainability\nviewpoints from which your next-gen apps will profit - and your users will\nbenefit. In this book you will follow the authors in the iterative evolution of\na real project from conception to distribution - all with commentary, complete\ncode resources, built, and packaged Native Apps for reference and staged Capture\nthe Flag (CTF) challenges that progress in difficulty as your comprehension of\nthe system grows. ### About the Topic Tauri is a brand new way to make\ncross-platform native-apps for web, desktop and mobile. At this very moment, the\npre-alpha version of this MIT licensed community-based software is being\nprepared for public release: https://github.com/tauri-apps/tauri Tauri\nintroduces novel methods for WebView integration and innovative patterns for\nrobust threat evasion. The 1.0 release will ship with a multipurpose white-box\nanalyzer and decompiler for any kind of binary and an integrated CLI for\ningesting any type of HTML; which, when combined, provides developers and\nsecurity teams with a holistic platform that has never existed as a single unit\nbefore. Tauri bridges communities and opens up new opportunities for everyone\nfrom the front end developer all the way to the low-level security and network\nadministrators. Due to this level of complexity and robustness, it is important\nto publish a reference guide that will necessarily be updated as major versions\nare released. ### What you will learn By the end of this book you will\nunderstand: - The method and reasoning behind the design of Tauri - The options\nyou have when building with Tauri - That having a moral compass is possible in\nsoftware development - Why the Rust language makes the most sense as a binding\nand application layer - Why Electron, Cordova, React Native, Capacitor and\nothers are no longer the best choice - Why a binary review is important And you\nwill be able to: - Transform a simple website project into a Tauri Native-App -\nMake a variety of Tauri Application Types based on the main Patterns - Decompile\nand analyze your App for Security Issues - Publish your App to a variety of App\nStores - Read and write Rust code ### Stuff you'll get if you preorder - Access\nto a real demo App built for all platforms available at respective stores (that\nincludes CTF Flags). - Exclusive One-Pager cheat sheets made available for each\nsection of the book, including the Appendices. - Early access to videos /\nwebcasts. - Discounted participation in the “Capture the Flag” event hosted at\nthe launch of the book. ## Outline This is an early outline of the contents that\nwe expect to publish. Contents subject to change. ### Chapter 1 - Theory (ca. 50\npages - mostly conversational / technical, graphics) ``` 1. Security Starts with\nYou 2. Privacy Ends with ${you} 3. Languages, Dialects and Patterns 4.\nToolchains and Syntactic Sugar 5. Production Methodologies 6. Enterprise\nReadiness 7. Message Queueing 8. Embracing Chaos 9. Distribution Techniques 10.\nLicensing Strategies ``` ### Chapter 2 - Practice (ca. 130 pages w/ charts,\nscreenshots, code samples) ``` 1. Environment Prerequisites - Node, Npm, Yarn,\nRustc, Rustup, Buildtools 2. Development Platform Details - macOS - Windows -\nLinux - Docker - Virtual Machines - CI / CD 3. Tauri Introduction 4. Tauri\nAnatomy 5. Tauri Configuration - Files & Folders - Icons - Splash Screens -\nWindow - `src-tauri/tauri.conf.json` 6. Preparing your code - Transpile dynamic\nimports - Remove webpack chunking - Monolithic Files - Minification strategies\n7. Tauri API - Design Considerations - API Usage Patterns - Custom API Functions\n- Endpoints - All - Answer - Bridge - Event - Execute - List Files - Open - Read\nBinary File - Read Text File - Set Title - Window - Write File 8. Web APIs 9.\nTauri App Extensions - Anatomy - Flow - Registration - Publication - API 10.\nTaskbar Integration (Desktop Only) - Anatomy - Integrations - macOS - Windows -\nLinux 11. Security Features - Baseline Rust Features - Functional Address Space\nLayout Randomization (fASLR) - Ahead of Time (AoT) Compilation - Content\nSecurity Policy (CSP) - One Time Pads (OTP) - Embedded Server: False - API\nTree-Shaking - Matryoschkasumming (with Tauri-Frida) 12. Bridges and Brokers -\nBridge Patterns - Message hashing with OTP - Plugin Pattern - Kamikaze Function\nInjection (KFI) Closures 13. Testing - Unit Testing - Rust - JS - Integration\nTesting - e2e Testing 14. Building - Debugging - Packaging - Minification -\nDistribution Platform Details - macOS (.app / .dmg) - Win (.exe / .msi) - Linux\nArm64 (.appImage / .deb) - Linux x64 (.appImage / .deb) - iOS (.ipa) - Android\n(.apk) - PWA Website (with wasm) - Code Signing - Keystores - Certs -\nFingerprints - Providing License for End Users - Providers - Keys Files -\nSelf-Updater - Anatomy - Service Provisioning - Github - AWS - Homegrown -\nCross-Platform Bundler 15. Tauri-Frida Harness - Introduction to Reverse\nEngineering - Toolchain - Usage - Binary Hooking at Runtime - Pointer Evaluation\n- Spraying, Fuzzing, Spoofing - Report Generation - Recompilation - Post-Binary\nAnalysis 16. Distribution - Git - Mac Store - iOS Store - Play store - Windows\nStore - Snap Store - PureOS Store - .deb channels - .tar.gz - homebrew - Fdroid\n- Cydia - ChromeOS - WASM ``` ### Chapter 3 - Philosophical Discourses (ca. 40\npages of essays, some graphics) ``` 1. Rights and Responsibilities (with Robin\nvan Boven (SFOSC)) - Who You are Responsible To - Being a Vendor Comes with\nDuties - Ubiquitous Resources are Still Precious - Use Policy to Address\nResponsibilities - Take a Hippocratic Development Oath 2. Take a More Secure\nStance (with Liran Tal (SNYK)) - Security Benefits of Frameworks - Encrypt All\nthe Things, All the Time - Constantly Audit Project Dependencies - Harden\nYourself, Your Organization and Your Ecosystem - “Do What You Can Until You Run\nOut of Time.” - [ROBERT C. SEACORD] 3. Production Strategies for Sustainability\n(with Rhys Parry (Independent)) - Develop in the “Perfect” Environment - Minimal\nImpact for Existing Enterprise Architectures - Use Low-Barrier Tools for\nEnsuring Wholestack Security - Test the Right Things Intelligently - Post-Binary\nAnalysis and Redistribution - The Last Mile ``` ### Chapter 4 - Execution (ca.\n100 pages w/ code examples, screenshots, graphics) ``` 1. Base Pattern Evolution\n- Hermit - Bridge - Cloudish - Cloudbridge - Lockdown - Multiwin - GLUI 2.\nAdvanced Patterns - Cryptographic Enclave - Identity Management - Combine an App\nwith a Daemon - IPC / RPC - Integrate with DENO 3. UI Source Complilation -\nReact - Vue - Angular - Svelte - Gatsby 4. Building a Real App - Multiparty\nPassword Manager - Design - Prototyping - Testing - Debugging - Packaging -\nChecksumming 5. Tauri-Frida - White Box Reversing - Analyzing with Frida - Chaos\nExperiments - Interface Jacking - Disk Change - Latency - Process Kill - CPU\nThrottle - Static Analysis Reporting - Binary Repackaging - Inject License Keys\n- Clear Dead Codepoints - Recalculate Integrated Checksum 6. Publishing the App\n- Git - Mac Store - iOS Store - Play store - Windows Store - Snap Store - PureOS\nStore - .deb channels - .tar.gz - homebrew - Fdroid - Cydia - ChromeOS - WASM 7.\nPublishing an Update ``` ### Chapter 5 - Appendices (ca. 120 pages) ``` 1.\nConfiguration Options 2. Files and Repositories 3. Tauri CLI references 4. Tauri\nAPI references 5. ES6 References 6. Rust References 7. App Pattern Charts 8.\nTauri-Frida Reference 9. Glossary 10. Index ``` ## Errata Got something that you\nthink should be in the book? Want to be our publisher? Reach out to us and let\nus know!","url":"https://tauri.studio/docs/about/book"},{"id":"prose_docs_about_governance_md","title":"Governance","area":"about","section":"about","headings":["Sustainability"],"subHeadings":["Organizational Structure","Code of Conduct","Social Contract","Licensing","Trademark"],"code":[],"text":"## Sustainability One of the main goals of the organizational structure of Tauri\nis to guarantee the sustainability of Tauri and the health and well-being of its\ncontributors. The world of Open Source is fraught with peril and discord, and we\nhave taken measures to ensure the longevity of Tauri. This document explains how\nwe go about doing so. ### Organizational Structure Tauri apps is governed by the\ncommunity and work is done in the context of public working groups. Each working\ngroup has a dedicated channel on the Discord server as well as a Team on GitHub.\nOther than that, each WG is free to use whatever type of organizational model it\nchooses. The current working groups are: - WG Governance & Guidance - WG Tech -\nWG Education - WG Media - WG Security - WG Devops With the exception of the\nsecurity working group, which is by invite only and convenes privately, all\nother working groups are public and open to any and all participants. Please\nvisit [this repository](https://github.com/tauri-apps/governance-and-guidance)\nto get more information. ### Code of Conduct Everyone participating in the Tauri\ncommunity is expected to follow a code of conduct that you can at the\n[Governance and Guidance:Code of\nConduct](https://github.com/tauri-apps/governance-and-guidance/blob/master/CODE_OF_CONDUCT.md).\n### Social Contract We have a Social Contract that informs our decision making\nand organization. You can read about it here: [Governance and Guidance:Social\nContract](https://github.com/tauri-apps/governance-and-guidance/blob/master/SOCIAL_CONTRACT.md).\n### Licensing We, the contributors to Tauri Apps, use the MIT and Apache\nlicenses for all code content. Images and bodies of text, unless otherwise noted\nare CC-BY-ND-NC. ### Trademark It is a permissible use of the name \"Tauri App\"\nor the Tauri logo to show that a project uses Tauri. \"Tauri Studio\" is reserved\nfor use by the organization. Any language that gives the impression that the\nTauri organization approves, authorizes or otherwise supports a project, person\nor company is not permissible without written authorization from the Guidance\nand Governance Working Group.","url":"https://tauri.studio/docs/about/governance"},{"id":"prose_docs_about_intro_md","title":"What is Tauri?","area":"about","section":"about","headings":["Security First","Polyglots","Honest Open Source","The Future"],"subHeadings":[],"code":[],"text":"Tauri is a toolkit that helps developers make applications for the major desktop\nplatforms - using virtually any frontend framework in existence. The core is\nbuilt with Rust and the CLI leverages Node.js making Tauri a genuinely polyglot\napproach to creating and maintaining great apps. If you want to know more about\nthe technical details, then please visit the\n[Introduction](/docs/getting-started/beginning-tutorial). If you want to know\nmore about this project's philosophy - then keep reading.\n\n## Security First In today's world, every honest threat model assumes that the\nuser's device has already been compromised. This puts app developers in a\ncomplicated situation, because if the device is already at risk, how can the\nsoftware be trusted? Defense in depth is the approach we've taken. We want you\nto be able to take every precaution possible to minimise the surface area you\npresent to attackers. Tauri lets you choose which API endpoints to ship, whether\nor not you want a localhost server built into your app, and it even randomizes\nfunctional handles at runtime. These and other techniques form a secure baseline\nthat empowers you and your users. Slowing down attackers by making static\nattacks crushingly difficult and isolating systems from one another is the name\nof the game. And if you are coming from the Electron ecosystem - rest assured -\nby default Tauri only ships binaries, not ASAR files. By choosing to build Tauri\nwith security as a guiding force, we give you every opportunity to take a\nproactive security posture. ## Polyglots, not Silos Most contemporary frameworks\nuse a single language paradigm and are therefore trapped in a bubble of\nknowledge and idiom. This can work well for certain niche applications, but it\nalso fosters a kind of tribalism. This can be seen in the way that the React,\nAngular and Vue development communities huddle on their stacks, ultimately\nbreeding very little cross-pollination. This same situation can be seen in the\nRust vs Node vs C++ battlefields, where hardliners take their stances and refuse\nto collaborate across communities. Today, Tauri uses Rust for the backend - but\nin the not too distant future, other backends like Go, Nim, Python, Csharp etc.\nwill be possible. This is because we are maintaining the official Rust bindings\nto the [webview](https://github.com/webview) organisation and plan to let you\nswitch out the backend for your needs. Since our API can be implemented in any\nlanguage with C interop, full compliance is only a PR away. ## Honest Open\nSource None of this would make any sense without a community. Today software\ncommunities are amazing places where people help each other and make awesome\nthings - open source is a very big part of that. Open source means different\nthings to different people, but most will agree that it serves to support\nfreedom. When software doesn't respect your rights, then it can seem unfair and\npotentially compromise your freedoms by operating in unethical ways. This is why\nwe are proud that FLOSS advocates can build applications with Tauri that are\n\"certifiably\" open source and can be included in FSF endorsed GNU/Linux\ndistributions. ## The Future Tauri's future depends on your involvement and\ncontributions. Try it out, file issues, join a working group or make a donation\n- every contribution is important. Please, at any rate, do get in touch!!!","url":"https://tauri.studio/docs/about/intro"},{"id":"prose_docs_about_security_md","title":"Security","area":"about","section":"about","headings":["No Server Required","Language Features of Rust","Dynamic Ahead of Time Compilation ","Function Hardening","System Features","Ecosystem","Future Work"],"subHeadings":["Security Researchers","Functional ASLR","Kamikaze Function Injection","Bridge","One Time Pad Tokenization and Hashing","Allowing API","Content Security Policy Management","Decompilation is Difficult","Build Pipelines and Artifact Authenticity","Resilient PR and Approval Processes","Signed Binaries","Post","Post","Audits"],"code":[],"text":"This guide seeks to explain the high level concepts and Security Features at the\ncore of Tauri's design that make you, your apps and your users safer by default.\nPlease note:\nWhile we take every opportunity to help you harden your application - there are\nalways underlying threats like BIOS attacks, memory rowhammering and other\noperating system vulnerabilities that are constantly being discovered and (in\nthe best cases) responsibly disclosed.\nFurthermore, there are many ways that development teams can cut corners and\neither leak sensitive information or leave doors wide open to any of a range of\nattacks. Security is a never-ending quest, and your users count on you to keep\nthem safe.\nTherefore, we highly recommend that you take some time to consider the security\nramifications of everything that your application does, especially in the\ncontext of running on the semi-hostile platform of end-user devices.\nIf you need help or want a review, you are welcome to contact the Tauri team for\nsecurity consultation.\n### Security Researchers If you feel that there is a security concern or issue\nwith anything in Tauri, please do not publicly comment on your findings.\nInstead, reach out directly to our security team: > security@tauri.studio\nAlthough we do not currently have a budget for Security Bounties, in some cases\nwe will consider rewarding responsible disclosure with our limited resources. ##\nNo Server Required Tauri enables you to construct an application that uses\nweb-technology for the user interface without requiring you to use a server to\ncommunicate with the backend. Even if you used advanced techniques of dynamic\nimports and offload work to the backend, no traffic can be sniffed on TCP ports\nor external processes - because they just aren't there. This reduces not only\nthe physical and virtual footprint of your final binary by a good deal, it also\nreduces the surface area of potential attack vectors by removing them from the\nequation. ## Language Features of Rust By turning to the programming language\nrenowned for its memory-safety and speed, Tauri simply erases whole classes of\nconventional attacks. `Use after free` just isn't something that can happen with\nTauri. ## Dynamic Ahead of Time Compilation (AOT) This process of compilation\nhappens several times during the bootstrapping phase of a Tauri app. By using\nour default dynamic Ahead of Time compiler, you can generate code references\nthat are unique for every session and are still technically static code units.\n## Function Hardening ### Functional ASLR Functional address Space Layout\nRandomization techniques randomize function names at runtime and can implement\nOTP hashing so no two sessions are ever the same. We propose a novel type of\nfunction naming at boot time and optionally after every execution. Using a UID\nfor each function pointer prevents static attacks. ### Kamikaze Function\nInjection This advanced type of fASLR using the `EVENT` API endpoint, is a\npromise wrapped in a closure (with randomized handle) that Rust inserts at\nruntime into the WebView, where its interface is locked within the promise\nresolution handler and is nulled after execution. ### Bridge, don't serve\nInstead of passing potentially unsafe functions, an event bridge can be used to\npass messages and commands to named brokers at each respective side of the\napplication. ### One Time Pad Tokenization and Hashing Hashing important\nmessages with a OTP salt, you are able to encrypt messages between the user\ninterface and the Rust backend. We are currently investigating the use of\nadditional sources of entropy such as the amazing [Infinite Noise\nTRNG](https://13-37.org/en/shop/infinite-noise-trng/). ## System Features ###\nAllowing API You have the ability to pick and choose which API functions are\navailable to the UI and to Rust. If they are not enabled, the code will not be\nshipped with your app, which reduces binary size and attack surface. They are\nopt-in, so you have to consciously choose to progressively enhance your\napplication. ### Content Security Policy Management Preventing unauthorized code\nexecution for websites has long since been \"resolved\" by using CSPs. Tauri can\ninject CSPs into the index.html of the user interface, and when using a\nlocalhost server it will also send these headers to the UI or any other clients\nthat connect with it. ### Decompilation is Difficult This means that your apps\ncannot be easily decompiled as is the case with Electron ASAR files, which makes\nthe process of reverse engineering your project much more time intensive and\nrequires specialist training. ## Ecosystem ### Build Pipelines and Artifact\nAuthenticity The process of releasing our source-code artifacts is highly\nautomated, yet mandates kickoff and review from real humans. Our current release\nstrategy uses a combination of Github Actions and IOTA Tangle publication ###\nResilient PR and Approval Processes Our WG-TECH reviews code changes, tags PRs\nwith scope and make sure that everything stays up to date. And when its time to\npublish a new version, one of the maintainers tags a new release on master,\nwhich: - validates core - runs smoke tests - audits security for crates and npm\n- generates changelogs - creates artifacts - publishes checksums to IOTA -\ncreates a draft release Then the maintainer reviews the release notes, edits if\nnecessary - and a new release is forged. ## Future Work ### Signed Binaries\nBecause the entire project is shipped within a monolithic binary, code can be\nsigned for all distributables. (Currently using external tooling, but we are\nactively working on making the bundler a one-stop-shop.) This makes it virtually\nimpossible for hackers to change an installed Application without the operating\nsystem noticing. [Reference](https://github.com/electron/asar/issues/123) ###\nPost-Binary Analysis Use industrial-grade pentester-tooling (via our forthcoming\nTauri-Frida GUI) to discover and fix security weaknesses in your final binaries.\n### Post-Binary Enhancement After the build is before the delivery, and Tauri\nwill provide you with tools never seen before. Stay tuned! ### Audits We are\ncurrently in the process of our first external audit. When complete, we will\npublish the results here.","url":"https://tauri.studio/docs/about/security"},{"id":"prose_docs_architecture_build_tools_md","title":"Node Build Tools","area":"architecture","section":"architecture","headings":[],"subHeadings":[],"code":[],"text":"This is a stub. Could add notes about Vite, Webpack, Rollup, etc.","url":"https://tauri.studio/docs/architecture/build-tools"},{"id":"prose_docs_architecture_frontend_frameworks_md","title":"Frontend Frameworks","area":"architecture","section":"architecture","headings":[],"subHeadings":[],"code":[],"text":"This is a stub. Could add notes about Vite, Webpack, Rollup, etc.","url":"https://tauri.studio/docs/architecture/frontend-frameworks"},{"id":"prose_docs_architecture_patterns_brownfield_md","title":"Brownfield Pattern","area":"architecture","section":"patterns","headings":["Incompatibilities","Configuration"],"subHeadings":[],"code":["json"],"text":"# Brownfield Pattern _**This is the default pattern.**_ This is the simplest and\nmost straightforward pattern to use Tauri with due to it trying to be the most\ncompatible with existing frontend projects as much as it can. In short, it tries\nto require nothing additional to what an existing web frontend might use inside\na browser. Not _**everything**_ that works in existing browser applications will\nwork out-of the box, see the [Incompatibility section](#incompatibilities) for\nmore details. If you are unfamiliar with Brownfield software development in\ngeneral, the [Brownfield Wikipedia\narticle](https://en.wikipedia.org/wiki/Brownfield_(software_development))\nprovides a nice summary of it. For Tauri, the existing software is current\nbrowser support and behavior instead of legacy systems. ## Incompatibilities The\nfirst incompatibility category is easy, any browser-specific APIs will not work\nproperly inside Tauri (even while using the Brownfield pattern). If the API is\nnot widely supported across browsers, it's likely not going to be supported\nacross all platforms while using Tauri. The second incompatibility category is\nfeatures that are planned for Tauri but are currently not fully implemented.\nHere is a list of examples: * [WebRTC support on\nLinux](https://github.com/tauri-apps/wry/issues/85) * [Some permissions\nAPIs](https://github.com/tauri-apps/wry/issues/81) * [Download Links/Blob as\nURL](https://github.com/tauri-apps/wry/issues/349) * [Better\ni18n](https://github.com/tauri-apps/wry/issues/442) ## Configuration Because the\nBrownfield pattern is the default pattern, no configuration option is required\nto be set. To explicitly set it, you can use the `tauri > pattern` object in the\n`tauri.conf.json` configuration file. ```json { \"tauri\": { \"pattern\": { \"use\":\n\"brownfield\" } } } ``` _**There are no additional configuration options for the\nbrownfield pattern.**_","url":"https://tauri.studio/docs/architecture/patterns/brownfield"},{"id":"prose_docs_architecture_patterns_isolation_md","title":"Isolation Pattern","area":"architecture","section":"patterns","headings":["Why","When","How","Recommendations","Creating the Isolation Application","Configuration"],"subHeadings":["Approximate Steps of an IPC Message","Performance Implications","Limitations"],"code":["html","js","json"],"text":"","url":"https://tauri.studio/docs/architecture/patterns/isolation"},{"id":"prose_docs_architecture_recipes_about_recipes_md","title":"A word on recipes","area":"architecture","section":"recipes","headings":[],"subHeadings":[],"code":[],"text":"Tauri recipes are descriptions of use-cases that are entirely configurable\nwithin the `src-tauri/tauri.conf.json` file. These are not the limits of what\nTauri can do, and there are probably more out there. If you discover one, why\nnot get in touch and help us update this collection! If you haven't read about\nthe general design of Tauri, then it would make the most sense for you to visit\nthe [\"Getting Started\"](/docs/getting-started/beginning-tutorial) and become\nfamiliar with the basic architecture and terminology used in these recipes.","url":"https://tauri.studio/docs/architecture/recipes/about-recipes"},{"id":"prose_docs_architecture_recipes_bridge_md","title":"Bridge","area":"architecture","section":"recipes","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":[],"text":"import Rater from '@theme/Rater' import useBaseUrl from '@docusaurus/useBaseUrl'\n\nEase of Use Extensibility Performance Security\n\nBridge [{useBaseUrl('img/recipes/Bridge.svg')}]\nPros:\n * Highly configurable\n * No Rust skills required\n\nCons:\n * Some WebAPIs unavailable\n * Challenge to implement\n\n## Description The Bridge recipe is a secure pattern where messages are passed\nbetween brokers via an implicit bridge using the API. It isolates functionality\nto scope and passes messages instead of functionality. ## Diagram import\nMermaid, { colors } from '@theme/Mermaid' F subgraph WEBVIEW F-.-E end D-->E\nE-->D B-->D D-->B subgraph RUST A==>H A-->B B-.-C B-.-G end A[Binary] B{Rust\nBroker} C[Subprocess 2] G[Subprocess 1] D(( API BRIDGE )) E{JS Broker} F[Window]\nH{Bootstrap} style D fill:#ccc,stroke:#333,stroke-width:4px,color:white style\nRUST fill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px\nstyle WEBVIEW\nfill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`} /> ##\nConfiguration Here's what you need to add to your tauri.conf.json file: ```json\n{ \"tauri\": { \"allowlist\": { \"all\": false, \"clipboard\": { \"all\": false,\n\"readText\": false, \"writeText\": false }, \"dialog\": { \"all\": false, \"ask\": false,\n\"confirm\": false, \"message\": false, \"open\": false, \"save\": false }, \"fs\": {\n\"all\": false, \"copyFile\": false, \"createDir\": false, \"readDir\": false,\n\"readFile\": false, \"removeDir\": false, \"removeFile\": false, \"renameFile\": false,\n\"scope\": [], \"writeFile\": false }, \"globalShortcut\": { \"all\": false }, \"http\": {\n\"all\": false, \"request\": false, \"scope\": [] }, \"notification\": { \"all\": false },\n\"os\": { \"all\": false }, \"path\": { \"all\": false }, \"process\": { \"all\": false,\n\"exit\": false, \"relaunch\": false, \"relaunchDangerousAllowSymlinkMacos\": false },\n\"protocol\": { \"all\": false, \"asset\": false, \"assetScope\": [] }, \"shell\": {\n\"all\": false, \"execute\": false, \"open\": false, \"scope\": [], \"sidecar\": false },\n\"window\": { \"all\": false, \"center\": false, \"close\": false, \"create\": false,\n\"hide\": false, \"maximize\": false, \"minimize\": false, \"print\": false,\n\"requestUserAttention\": false, \"setAlwaysOnTop\": false, \"setDecorations\": false,\n\"setFocus\": false, \"setFullscreen\": false, \"setIcon\": false, \"setMaxSize\":\nfalse, \"setMinSize\": false, \"setPosition\": false, \"setResizable\": false,\n\"setSize\": false, \"setSkipTaskbar\": false, \"setTitle\": false, \"show\": false,\n\"startDragging\": false, \"unmaximize\": false, \"unminimize\": false } } } } ```","url":"https://tauri.studio/docs/architecture/recipes/bridge"},{"id":"prose_docs_architecture_recipes_cloudbridge_md","title":"Cloudbridge","area":"architecture","section":"recipes","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":[],"text":"import Rater from '@theme/Rater' import useBaseUrl from '@docusaurus/useBaseUrl'\n\nEase of Use Extensibility Performance Security\n\nCloudbridge [{useBaseUrl('img/recipes/Cloudbridge.svg')}]\nPros:\n * All available features\n * No Rust skills required\n\nCons:\n * Largest bundle size\n * Hard to separate concerns\n\n## Description The Cloudbridge recipe combines the flexibility of a localhost\nand the security of the bridge. With so many features, it can be easy to get\nlost. ## Diagram import Mermaid, { colors } from '@theme/Mermaid' F2 H==>D2\nD2-->F2 F2-->D2 B-->D D-->B E2-->D D-->E2 subgraph WEBVIEW F2 E2 end subgraph\nSERVER D2 E-->D2 end subgraph RUST A==>H A-->B B-.-C end A[Binary] B{Rust\nBroker} C[Subprocess] D(( API BRIDGE )) E{JS Broker} D2(( localhost )) E[bundled\nresources] E2{JS Broker} F2[Window] H{Bootstrap} style D\nfill:#ccc,stroke:#333,stroke-width:4px,color:white style RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px style\nWEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px\nstyle SERVER fill:#49A24A,stroke:#2B6063,stroke-width:4px `} /> ## Configuration\nHere's what you need to add to your tauri.conf.json file: ```json \"tauri\": {\n\"allowlist\": { \"all\": true // enable entire API } } ```","url":"https://tauri.studio/docs/architecture/recipes/cloudbridge"},{"id":"prose_docs_architecture_recipes_cloudish_md","title":"Cloudish","area":"architecture","section":"recipes","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":[],"text":"import Rater from '@theme/Rater' import useBaseUrl from '@docusaurus/useBaseUrl'\n\nEase of Use Extensibility Performance Security\n\nCloudish [{useBaseUrl('img/recipes/Cloudish.svg')}]\nPros:\n * Similar to a SPA web-app\n * No Rust skills required\n\nCons:\n * No access to Rust API\n * Uses a localhost server\n\n## Description The Cloudish recipe is a pattern for maximum flexibility and app\nperformance. It uses a localhost server, which means that your app will\ntechnically be available to other processes, like browsers and potentially other\ndevices on the network. All of your assets are baked into the binary, but served\nas if they were distinct files. ## Diagram import Mermaid, { colors } from\n'@theme/Mermaid' F H==>D D-->F F-->D subgraph RUST A==>H end subgraph WEBVIEW F\nend subgraph SERVER D E-->D end A[Binary] D(( localhost )) E[bundled resources]\nF[Window] H{Bootstrap} style RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px style\nWEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px\nstyle SERVER fill:#49A24A,stroke:#2B6063,stroke-width:4px`} /> ## Configuration\nHere's what you need to add to your tauri.conf.json file: ```json \"tauri\": {\n\"allowlist\": { \"all\": false // disable entire API } } ```","url":"https://tauri.studio/docs/architecture/recipes/cloudish"},{"id":"prose_docs_architecture_recipes_glui_md","title":"GLUI","area":"architecture","section":"recipes","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":[],"text":"import Alert from '@theme/Alert' import useBaseUrl from '@docusaurus/useBaseUrl'\nThis pattern is not available for now. import Rater from '@theme/Rater'\n\nEase of Use Extensibility Performance Security\n\nGLUI [{useBaseUrl('img/recipes/GLUI.svg')}]\nPros:\n * Framebuffer FTW\n * Window events rigged\n\nCons:\n * Broken on your machine\n\n## Description The GLUI is a research pattern that we will use internally to\ntest approaches using a GLUTIN window. We’re not sure yet if it will make the\nfinal cut as a bona fide alternative to WebView, although early tests with\ntransparent and multiwindow are exciting. ## Diagram import Mermaid, { colors }\nfrom '@theme/Mermaid' H H==>G A-->D D-->G subgraph GLUTIN G end subgraph RUST A\nend A[Binary] D(Framebuffer) G[GL Window] H{Bootstrap} style GLUTIN\nstroke:${colors.blue.dark},stroke-width:4px style RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px`} />\n## Configuration Here's what you need to add to your tauri.conf.json file:\n```json \"tauri\": { \"allowlist\": { // all API endpoints are default false \"all\":\nfalse, // disable the api }, \"window\": { // not yet normative \"glutin\": true,\n\"webview\": false } } ```","url":"https://tauri.studio/docs/architecture/recipes/glui"},{"id":"prose_docs_architecture_recipes_hermit_md","title":"Hermit","area":"architecture","section":"recipes","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":["json"],"text":"import Rater from '@theme/Rater' import useBaseUrl from '@docusaurus/useBaseUrl'\n\nEase of Use Extensibility Performance Security\n\nHermit [{useBaseUrl('img/recipes/Hermit.svg')}]\nPros:\n * Quick to make\n * Smallest size\n\nCons:\n * No remote resources\n * No access to API\n\n## Description The Hermit recipe is a pattern for ultimate application isolation\nwhere all logic is self-contained in the Window and the binary exists merely to\nbootstrap the Window. There is no communication back to Rust from the Window,\nthere is no localhost server, and the Window has no access to any remote\nresources. The Hermit is great for interactive Kiosk Mode and standalone HTML\nbased games. ## Diagram import Mermaid, { colors } from '@theme/Mermaid' H H==>F\nsubgraph WEBVIEW F end subgraph RUST A end A[fa:fa-cog Binary ]\nF[fa:fa-window-maximize Window] H{Bootstrap} style RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px style\nWEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`}\n/> ## Configuration Here's what you need to add to your tauri.conf.json file:\n```json \"tauri\": { \"allowlist\": { \"all\": false, // disable and tree-shake all\napi functions } } ```","url":"https://tauri.studio/docs/architecture/recipes/hermit"},{"id":"prose_docs_architecture_recipes_lockdown_md","title":"Lockdown","area":"architecture","section":"recipes","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":["json"],"text":"import Rater from '@theme/Rater' import useBaseUrl from '@docusaurus/useBaseUrl'\n\nEase of Use Extensibility Performance Security\n\nLockdown [{useBaseUrl('img/recipes/Lockdown.svg')}]\nPros:\n * Highest security rating\n * Elegant and powerful\n\nCons:\n * Rust skills required\n * No remote resources\n\n## Description The Lockdown recipe is a minimal usage of the [Bridge\npattern](./bridge.md), which only allows interaction between Rust and the Window\nvia expiring JS Promise Closures that are injected into the Window by Rust and\nnulled as part of the callback. ## Diagram import Mermaid, { colors } from\n'@theme/Mermaid' F G-.->B B-->G subgraph WEBVIEW G-->F end subgraph RUST A-->B\nA==>H end A[Binary] B[API:Event] F[Window] G((Promise Closure)) H{Bootstrap}\nstyle RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px style\nWEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`}\n/> ## Configuration Here's what you need to add to your tauri.conf.json file:\n```json \"tauri\": { \"allowlist\": {} // all API endpoints are default false } ```","url":"https://tauri.studio/docs/architecture/recipes/lockdown"},{"id":"prose_docs_architecture_recipes_multiwin_md","title":"Multiwin","area":"architecture","section":"recipes","headings":["Description","Diagram","Configuration"],"subHeadings":[],"code":[],"text":"import Alert from '@theme/Alert' import useBaseUrl from '@docusaurus/useBaseUrl'\nimport Rater from '@theme/Rater'\n\nEase of Use Extensibility Performance Security\n\nMultiwin [{useBaseUrl('img/recipes/Multiwin.svg')}]\nPros:\n * Windows can be spawned or destroyed at runtime\n * Separation of concerns\n\nCons:\n * Somewhat complex\n\n## Description The Multiwin recipe will allow you to have multiple windows. ##\nDiagram import Mermaid, { colors } from '@theme/Mermaid' H H==>F H==>G subgraph\nWEBVIEW F end subgraph WINIT G end subgraph RUST A end A[Binary] F[Window]\nG[Window] H{Bootstrap} style WINIT stroke:${colors.blue.dark},stroke-width:4px\nstyle RUST\nfill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px style\nWEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`}\n/> ## Configuration Here's what you need to add to your tauri.conf.json file:\n```json \"tauri\": { \"allowlist\": {}, // all API endpoints are default false\n\"windows\": [{ \"title\": \"Window1\", \"label\": \"main\", }, { \"title\": \"Splash\",\n\"label\": \"splashscreen\" }] } ```","url":"https://tauri.studio/docs/architecture/recipes/multiwin"},{"id":"prose_docs_building_app_size_md","title":"Reducing the App Size","area":"building","section":"building","headings":["Checklist","1","2","3","4","5","6","7","8"],"subHeadings":["You can","Think twice before adding a dependency","Why","How","Why","How","Why","How","Why","How","Why","How","Why","How","Unstable Rust Compression Features","Why","How","Why","How"],"code":["css","json","toml","sh"],"text":"# Reducing the App Size At Tauri, we are working on reducing the environmental\nfootprint of applications by using system resources where available, providing\ncompiled systems that don't need runtime evaluation, and offering guides so that\nengineers can go even smaller without sacrificing on performance or security.\nThe point is, by saving resources, we are doing our part to help you help us\nsave the planet -- which is the only bottom line that companies in the 21st\nCentury should care about. So if you are interested in learning how to improve\nyour appsize and performance, read on dear friend: ### You can't improve what\nyou can't measure Before you can optimize your app you need to figure out what\nit is that takes up space in your app! Here are a couple of tools that can\nassist you with that: - **`cargo-bloat`** [`cargo-bloat`][cargo-bloat] is a rust\nutility to figure out what takes the most space in your app. It gives you a\nnice, sorted overview of the biggest rust functions. - **`cargo-expand`**\n[Macros] make your rust code more concise and easier to read, but they are also\nhidden size traps! Use [`cargo-expand`][cargo-expand] to see what all those\nmacros generate under the hood. - **`rollup-plugin-visualizer`**\n[`rollup-plugin-visualizer`][rollup-plugin-visualizer] generates beautiful (and\ninsightful) graphs from your rollup bundle. Very convenient for figuring out\nwhat JavaScript dependencies contribute to your final bundle size the most. -\n**`rollup-plugin-graph`** You noticed a dependency was included in your final\nfrontend bundle, but you are not sure why?\n[`rollup-plugin-graph`][rollup-plugin-graph] generates graphviz compatible\nvisualizations of your entire dependency graph. These are just a couple tools\nthat you might use, make sure to check your frontend bundlers plugin list for\nmore! ### Think twice before adding a dependency ## Checklist - [Reducing the\nApp Size](#reducing-the-app-size) - [You can't improve what you can't\nmeasure](#you-cant-improve-what-you-cant-measure) - [Think twice before adding a\ndependency](#think-twice-before-adding-a-dependency) - [Checklist](#checklist) -\n[1. Minify Javascript](#1-minify-javascript) - [Why?](#why) - [How?](#how) - [2.\nOptimize Dependecies](#2-optimize-dependecies) - [Why?](#why-1) - [How?](#how-1)\n- [3. Optimize Images](#3-optimize-images) - [Why?](#why-2) - [How?](#how-2) -\n[4. Remove Unnecessary Custom Fonts](#4-remove-unnecessary-custom-fonts) -\n[Why?](#why-3) - [How?](#how-3) - [5. Allowlist Config](#5-allowlist-config) -\n[Why?](#why-4) - [How?](#how-4) - [6. Rust Build-time\nOptimizations](#6-rust-build-time-optimizations) - [Why?](#why-5) -\n[How?](#how-5) - [Unstable Rust Compression\nFeatures](#unstable-rust-compression-features) - [7. Stripping](#7-stripping) -\n[Why?](#why-6) - [How?](#how-6) - [8. UPX](#8-upx) - [Why?](#why-7) -\n[How?](#how-7) - [Usage on macOS](#usage-on-macos) ## 1. Minify Javascript ###\nWhy? JavaScript makes up a large portion of a typical Tauri app, so it's\nimportant to make the JavaScript as lightweight as possible. ### How? You can\nchoose among a plethora of JavaScript bundlers, popular choices are [Vite],\n[webpack] and [rollup]. All of them can produce minified JavaScript if\nconfigured correctly, so please consult your bundler documentation for specific\noptions. Generally speaking however, you should make sure to: - **Enable tree\nshaking** This option removes unused JavaScript from your bundle. All popular\nbundlers enable this by default. - **Enable minification** Minification removes\nunnecessary whitespace, shortens variable names and applies various other\noptimizations. Most bundlers enable this by default, a notable exception is\n[rollup] where you need a plugins like [rollup-plugin-terser] or\n[rollup-plugin-uglify]. :::note Minifiers like [terser] and [esbuild] can also\nbe used as standalone tools. ::: - **Disable source maps** Source maps provide a\nnice developer experience when working with languages that compile to JavaScript\nsuch as [TypeScript]. As source maps tend to be quite large though, it's\nimportant that you disable them when building for production. They have no\nbenefit to your end user, so it's effectively dead weight. ## 2. Optimize\nDependecies Many popular libraries have smaller and faster alternatives that you\ncan choose instead. ### Why? Most libraries you use depend on a number of\nlibraries themselves, so a library that looks inconspicuous at first glance\nmight add **several megabytes** worth of code to your app. ### How? You can use\n[Bundlephobia] to find the cost of JavaScript dependencies. Inspecting the cost\nof rust dependencies is generally harder since the compiler will do a number of\noptimizations. If you find a library that seems excessively large, google\naround, chances are someone else already had the same though and created an\nalternative. A good example is [Moment.js] and it's [Many\nalternatives][you-dont-need-momentjs]. But keep in mind: **The best dependency\nis no dependency**, meaning that you should always prefer language builtins over\n3rd party packages. ## 3. Optimize Images ### Why? According to the [Http\nArchive], images are the [biggest contributor to website weight][http archive\nreport, image bytes]. So if your app includes have background images or icons,\nmake sure to optimize them! ### How? You can choose between a variety of manual\noptions ([GIMP], [Photoshop], [Squoosh]) or plugins for your favorite frontend\nbuild tools ([vite-imagetools], [vite-plugin-imagemin],\n[image-minimizer-webpack-plugin]). :::caution The `imagemin` library most of the\nplugins use is [officially unmaintained][imagemin is unmaintained]. ::: - **Use\nmodern image formats** Formats such as `webp` or `avif` offer size reductions of\n**up to 95%** compared to jpeg while maintaining excellent visual accuracy. You\ncan use tools such as [Squoosh] to try different formats on your images. -\n**Size images accordingly** No one will appreciate you shipping the 6K raw image\nwith your app, so make sure to size your image accordingly. Images that appear\nlarge on screen should be sized larger than images that take up less screen\nspace. - **Don't use Responsive Images** In a Web Environment it's recommended\nto use a [Responsive Images] as they will dynamically load the correct image\nsize for each user. You are not building a simple website though: All your\nimages are already downloaded. So using Responsive Images will only bloat your\napp with redundant copies. - **Remove Metadata** Images taken straight from a\ncamera or stock photo side often include metadata about the Camera and Lens\nmodel or Photographer. Not only are those wasted bytes, metadata properties can\nalso hold potentially sensitive information such as the time, day and location\nof the photo. ## 4. Remove Unnecessary Custom Fonts Consider not shipping custom\nfonts with your app and relying on system fonts instead. If you must ship custom\nfonts, make sure they are in modern, optimized formats such as `woff2`. ### Why?\nFonts can be quite large in size, so using the fonts already included in the\nOperating System will reduce your apps footprint. It will also avoid FOUT (Flash\nof Unstyled Text) and make your app feel more \"native\" since it uses the same\nfont as all other apps. If you must include a custom fonts, make sure you\ninclude them in modern formats such as `woff2` as those tend to be way smaller\nthan legacy formats. ### How? Use so called **\"System Font Stacks\"** in your\nCSS. There are number of variations, but here are 3 basic ones to get you\nstarted: - **Sans-serif** ```css font-family: -apple-system, BlinkMacSystemFont,\n'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';\n``` - **Serif** ```css font-family: Iowan Old Style, Apple Garamond,\nBaskerville, Times New Roman, Droid Serif, Times, Source Serif Pro, serif, Apple\nColor Emoji, Segoe UI Emoji, Segoe UI Symbol; ``` - **Monospace** ```css\nfont-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation\nMono, monospace; ``` ## 5. Allowlist Config You can reduce your apps size by\nonly enabling the tauri api features you need in the `allowlist` config. ###\nWhy? The `allowlist` config determines what api features to enable, disabled\nfeatures will **not be compiled into your app**. This is a great way of shedding\nsome extra weight. ### How? And example from a typical `tauri.conf.json`:\n```json { \"tauri\": { \"allowlist\": { \"all\": false, \"fs\": { \"writeFile\": true },\n\"shell\": { \"execute\": true }, \"dialog\": { \"save\": true } } } } ``` ## 6. Rust\nBuild-time Optimizations Configure your cargo project to take advantage of rusts\nsize optimization features. [Why is a rust executable large ?] provides an\nexcellent explanation on why this matters and an in depth walkthrough, while\n[Minimizing Rust Binary Size] is more up to date and has a couple\nrecommendations. ### Why? Rust is notorious for producing rather large binaries,\nbut the compiler offers a number of options to improve the final size. ### How?\nCargo exposes a number of options that determine how the compiler generates your\nbinary. The \"recommended\" options for tauri apps are these: ```toml\n[profile.release] panic = \"abort\" # Strip expensive panic clean-up logic\ncodegen-units = 1 # Compile crates one after another so the compiler can\noptimize better lto = true # Enables link to optimizations opt-level = \"s\" #\nOptimize for binary size ``` :::note There is also `opt-level = \"z\"` available\nto try to reduce the resulting binary size. `\"s\"` and `\"z\"` can sometimes be\nsmaller than the other, so test it with your own application! We've seen smaller\nbinary sizes from `\"s\"` for Tauri example applications, but real world\napplications can always differ. ::: For a detailed explanation of each option\nand a bunch more, refer to the [Cargo books Profiles section][cargo profiles].\n### Unstable Rust Compression Features :::caution The following suggestions are\nall unstable features and require a nightly toolchain. See the [Unstable\nFeatures][cargo unstable features] documentation for more information of what\nthis involves. ::: The following methods involve using unstable compiler\nfeatures and require having a rust nightly toolchain installed. If you don't\nhave the nightly toolchain + `rust-src` nightly component added, try the\nfollowing: ```sh $ rustup toolchain install nightly $ rustup component add\nrust-src --toolchain nightly ``` The Rust Standard Library comes precompiled.\nYou can instead apply the optimization options used for the rest of your binary\n+ dependencies to the std with an unstable flag. This flag requires specifying\nyour target, so know the target triple that you are targeting. ```sh $ cargo\n+nightly build --release -Z build-std --target x86_64-unknown-linux-gnu ``` If\nyou are using `panic = \"abort\"` in your release profile optimizations, then you\nneed to make sure the `panic_abort` crate is compiled with std. Additionally, an\nextra std feature can be used to further reduce the binary size. The following\napplies both: ```sh $ cargo +nightly build --release -Z\nbuild-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target\nx86_64-unknown-linux-gnu ``` See the unstable documentation for more details\nabout [`-Z build-std`][cargo build-std] and [`-Z build-std-features`][cargo\nbuild-std-features]. ## 7. Stripping Use strip utilities to remove debug symbols\nfrom your compiled app. ### Why? Your compiled app will include so-called \"Debug\nSymbols\" that include information such as function and variable names. As your\nend users will most likely not care about debug symbols this is a pretty\nsurefire way to save some bytes! ### How? The easiest way is to use the famous\n`strip` utility to remove this debugging information. ```sh $ strip\ntarget/release/my_application ``` See your local `strip` manpage for more\ninformation and flags that can be used to specify what information gets stripped\nout from the binary. ## 8. UPX UPX, **Ultimate Packer for eXecutables**, is a\ndinosaur amongst the binary packers. This 23-year old, well-maintained piece of\nkit is GPL-v2 licensed with a pretty liberal usage declaration. Our\nunderstanding of the licensing is that you can use it for any purposes\n(commercial or otherwise) without needing to change your license unless you\nmodify the source code of UPX. ### Why? Maybe your target audience has very slow\ninternet, or your app needs to fit on a really small USB stick and all the above\nsteps haven't resulted in the savings you need. Fear not, as we have one last\ntrick up our sleeves: [UPX] compresses your binary and creates a self-extracting\nexecutable that will decompress itself at runtime. ### How? :::caution You\nshould know that this technique might flag your binary as a virus on Windows and\nmacOS - so use at your own discretion, and as always validate with [Frida] and\ndo real distribution testing! ::: #### Usage on macOS ```sh $ brew install upx $\nyarn tauri build $ upx --ultra-brute\nsrc-tauri/target/release/bundle/macos/app.app/Contents/macOS/app Ultimate Packer\nfor eXecutables Copyright (C) 1996 - 2018 UPX 3.95 Markus Oberhumer, Laszlo\nMolnar & John Reiser Aug 26th 2018 File size Ratio Format Name\n-------------------- ------ ----------- ----------- 963140 -> 274448 28.50%\nmacho/amd64 app ``` [cargo-bloat]: https://github.com/RazrFalcon/cargo-bloat\n[Macros]: https://doc.rust-lang.org/book/ch19-06-macros.html [cargo-expand]:\nhttps://github.com/dtolnay/cargo-expand [rollup-plugin-visualizer]:\nhttps://github.com/btd/rollup-plugin-visualizer [rollup-plugin-graph]:\nhttps://github.com/ondras/rollup-plugin-graph [vite]: https://vitejs.dev\n[webpack]: https://webpack.js.org [rollup]: https://rollupjs.org/guide/en/\n[rollup-plugin-terser]: https://github.com/TrySound/rollup-plugin-terser\n[rollup-plugin-uglify]: https://github.com/TrySound/rollup-plugin-uglify\n[terser]: https://terser.org [esbuild]: https://esbuild.github.io [typescript]:\nhttps://www.typescriptlang.org [moment.js]: https://momentjs.com\n[you-dont-need-momentjs]:\nhttps://github.com/you-dont-need/You-Dont-Need-Momentjs [http archive]:\nhttps://httparchive.org [http archive report, image bytes]:\nhttps://httparchive.org/reports/page-weight#bytesImg [imagemin is unmaintained]:\nhttps://github.com/imagemin/imagemin/issues/385 [gimp]: https://www.gimp.org\n[photoshop]: https://www.adobe.com/de/products/photoshop.html [vite-imagetools]:\nhttps://github.com/JonasKruckenberg/imagetools [vite-plugin-imagemin]:\nhttps://github.com/vbenjs/vite-plugin-imagemin [image-minimizer-webpack-plugin]:\nhttps://github.com/webpack-contrib/image-minimizer-webpack-plugin [squoosh]:\nhttps://squoosh.app [responsive images]:\nhttps://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images\n[why is a rust executable large ?]:\nhttps://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html\n[minimizing rust binary size]: https://github.com/johnthagen/min-sized-rust\n[cargo unstable features]:\nhttps://doc.rust-lang.org/cargo/reference/unstable.html#unstable-features [cargo\nprofiles]: https://doc.rust-lang.org/cargo/reference/profiles.html [cargo\nbuild-std]: https://doc.rust-lang.org/cargo/reference/unstable.html#build-std\n[cargo build-std-features]:\nhttps://doc.rust-lang.org/cargo/reference/unstable.html#build-std-features\n[Bundlephobia]: https://bundlephobia.com [Frida]: https://frida.re/docs/home/\n[UPX]: https://github.com/upx/upx","url":"https://tauri.studio/docs/building/app-size"},{"id":"prose_docs_building_cross_platform_md","title":"Cross-Platform Compilation","area":"building","section":"building","headings":[],"subHeadings":[],"code":[],"text":"How to use GH Action for Building: a glance at Tauri Action.","url":"https://tauri.studio/docs/building/cross-platform"},{"id":"prose_docs_building_debian_md","title":"Debian packages","area":"building","section":"building","headings":[],"subHeadings":[],"code":["json"],"text":"import Alert from '@theme/Alert' Tauri allows your app to be packaged as a\n`.deb` (Debian package) file. # Bootstrapper Instead of launching the app\ndirectly, you can configure the bundled app to run a script that tries to expose\nthe environment variables to the app; without that you'll have trouble using\nsystem programs because the `PATH` environment variable isn't correct. Enable it\nwith the `useBootstrapper` [/docs/api/config#tauri.bundle.deb.useBootstrapper]\nconfig. # Custom files To include custom files to the debian package, you can\nconfigure a mapping on `tauri.conf.json > tauri > bundle > deb > files` as\nfollows: ```json { \"tauri\": { \"bundle\": { \"deb\": { \"files\": {\n\"/usr/lib/README.md\": \"../README.md\", // copies the README.md file to\n/usr/lib/README.md \"usr/lib/assets\": \"../public/\" // copies the entire public\ndirectory to /usr/lib/assets } } } } } ``` Each `files` object key is the path\non the debian package, and the value is a path to a file or directory relative\nto the `tauri.conf.json` file.","url":"https://tauri.studio/docs/building/debian"},{"id":"prose_docs_building_introduction_md","title":"Introduction","area":"building","section":"building","headings":[],"subHeadings":[],"code":[],"text":"The Tauri Bundler is a Rust harness for compiling your binary, packaging assets,\nand preparing a final bundle. It will detect your operating system and build a\nbundle accordingly. It currently supports: - Linux: .deb, .appimage - macOS:\n.app, .dmg - Windows: .exe, .msi","url":"https://tauri.studio/docs/building/introduction"},{"id":"prose_docs_building_sidecar_md","title":"Sidecar (Embedding External Binaries)","area":"building","section":"building","headings":["Running the sidecar binary on JavaScript","Running the sidecar binary on Rust","Using Node"],"subHeadings":[],"code":["json","bash","javascript","rust"],"text":"import Alert from '@theme/Alert' You may need to embed depending binaries in\norder to make your application work or to prevent users having to install\nadditional dependencies (e.g. Node.js, Python, etc). To bundle the binaries of\nyour choice, you can add the `externalBin` property to the `tauri > bundle`\nobject in your `tauri.conf.json`. See more about tauri.conf.json configuration\nhere [/docs/api/config#tauri.bundle]. `externalBin` expects a list of strings\ntargeting binaries either with absolute or relative paths. Here is a sample to\nillustrate the configuration, this is not a complete `tauri.conf.json` file:\n```json { \"tauri\": { \"bundle\": { \"externalBin\": [\"/absolute/path/to/app\",\n\"relative/path/to/binary\", \"bin/python\"] } } } ``` A binary with the same name\nand a `-$TARGET_TRIPLE` suffix must exist on the specified path. For instance,\n`\"externalBin\": [\"bin/python\"]` requires a\n`src-tauri/bin/python-x86_64-unknown-linux-gnu` executable on Linux. You can\nfind the current platform's target triple running the following command: ```bash\nrustc -Vv | grep host | cut -f2 -d' ' ``` Here's a Node.js script to append the\ntarget triple to a binary: ```javascript const execa = require('execa') const fs\n= require('fs') let extension = '' if (process.platform === 'win32') { extension\n= '.exe' } async function main() { const rustInfo = (await execa('rustc',\n['-vV'])).stdout const targetTriple = /host: (\\S+)/g.exec(rustInfo)[1] if\n(!targetTriple) { console.error('Failed to determine platform target triple') }\nfs.renameSync( `src-tauri/binaries/app${extension}`,\n`src-tauri/binaries/app-${targetTriple}${extension}` ) } main().catch((e) => {\nthrow e }) ``` ## Running the sidecar binary on JavaScript On the JavaScript\ncode, import the `Command` class on the `shell` module and use the `sidecar`\nstatic method: ```javascript import { Command } from '@tauri-apps/api/shell' //\nalternatively, use `window.__TAURI__.shell.Command` // `my-sidecar` is the value\nspecified on `tauri.conf.json > tauri > bundle > externalBin` const command =\nCommand.sidecar('my-sidecar') const output = await command.execute() ``` ##\nRunning the sidecar binary on Rust On the Rust code, import the `Command` struct\nfrom the `tauri::api::process` module: ```rust let (mut rx, mut child) =\nCommand::new_sidecar(\"my-sidecar\") .expect(\"failed to create `my-sidecar` binary\ncommand\") .spawn() .expect(\"Failed to spawn sidecar\");\ntauri::async_runtime::spawn(async move { // read events such as stdout while let\nSome(event) = rx.recv().await { if let CommandEvent::Stdout(line) = event {\nwindow .emit(\"message\", Some(format!(\"'{}'\", line))) .expect(\"failed to emit\nevent\"); // write to stdin child.write(\"message from\nRust\\n\".as_bytes()).unwrap(); } } }); ``` ## Using Node.js on a sidecar The\nTauri [sidecar\nexample](https://github.com/tauri-apps/tauri/tree/dev/examples/sidecar)\ndemonstrates how to use the sidecar API to run a Node.js application on Tauri.\nIt compiles the Node.js code using [pkg](https://github.com/vercel/pkg) and uses\nthe scripts above to run it.","url":"https://tauri.studio/docs/building/sidecar"},{"id":"prose_docs_community_ci_cd_md","title":"CI/CD","area":"community","section":"community","headings":["Continuous Integration","Continuous Deployment"],"subHeadings":["Introduction to immutable checksum","Next Steps"],"code":["yml"],"text":"## Continuous Integration Github Actions has two triggers of which we make heavy\nuse: `push` and `pull_request`. Every commit that made to the repo is a `push`.\nWhen you open a pull request from a branch (call it `great_feature`) to another\nbranch (our working branch, `dev`), each commit to `great_feature` would\npossibly trigger both of these events. We can use a filter to focus on the\nevents we care about though. In our workflows, we only PR (pull request) the\n`dev` and `master` branches. This means that if we filter to only the `dev` and\n`master` branches on commit, we will only run that workflow when we _merge_ a\nPR. A merged PR typically only occurs once a day or less so this will be a good\nfit for the longer running tests, e.g. the smoke tests in our case. Below is how\nthat might look. Unit tests: ```yml # these run fast so we can have them run on\nany commit name: unit tests on: pull_request: push: branches: - dev - master ```\nSmoke tests: ```yml # these run slower so we run only on merges to dev or master\nbranch name: smoke tests on: push: branches: - dev - master ``` Tauri operates\noff the `dev` branch as default, and merges to `master` for release. With these\nGithub Actions set up, we will run the unit tests on every commit to an open PR\n(see `pull_request`). When that PR is merged into `dev`, we will run both the\nunit tests and the smoke tests. ## Continuous Deployment ### Introduction to\nimmutable checksum It is not only possible, but trivial to modify release notes\nand artifacts after it has been published on Github. While there are very valid\nreasons for doing this, it is not exactly a totally trustworthy method - i.e.\nyou have no guarantee that what you are reading is really reflective of the\nunderlying truth or the tarballs. It is technically possible to change downloads\nover the wire or in the box or change checksums in targeted attacks. What we are\nseeking to accomplish is a best case scenario where: 1. Human error is reduced\nto a minimum, but humans are still integral in the actual release 2. Machine\nbuilt assets, changelogs and attached security audits are verifiable with\nchecksums that are published in an immutable, globally available store. To this\nend we fashioned a workflow shown below. As it stands now, we have #3 through #6\nimplemented. We manually do #2 which then feeds into #3 and kicks off the rest\nof the automatic workflow. 1. a human pushes to dev through a pull request (can\nhappen any number of times) - pull request includes a changeset file describing\nthe change and required version bump 2. a pull request is created (or updated)\nto include the change and version bump - this pull request stays open and will\nbe force pushed until it gets merged (and published) - increase the version\nnumber based on changesets - delete all changeset files 3. a codeowner merges\nthe publish PR to dev (no direct push permissible for anyone) - all tests (unit,\ne2e, smoke tests) are run on the PR - failures prevent the publish so they must\npass before merge 4. merge to dev triggers release sequence - changes are\nsquashed and a PR is opened against master 5. when PR to master is merged... -\nvulnerability audit (crates and yarn) and output saved - checksums and metadata\nand output saved - packages are published on npm/cargo, tarball/zip created -\nrelease is created for each package that had updates (if version isn't changed,\nbuild skips the publish steps) - output from audit/checksums is piped into the\nrelease body - tarball / zip attached to release - async process to publish to\nIOTA tangle (feeless) via release tag [note: still have things to resolve here]\n6. release is complete - master has updated code and tagged - GitHub release has\ntarballs, checksums, and changelog (may have multiple releases if more than one\npackage published) [note: is part of step 2 and is not yet implemented] ### Next\nSteps Next steps may include transferring and publishing the built assets to\nadditional places: 1. Tauri's private verdaccio 2. IPFS 3. PureOS Gitlab 4.\nGitHub Packages We can also do some interesting things like signing our\nreleases, including a hash in the release and/or even publishing this\ninformation on a blockchain that it can be easily verified. Publishing on the\nblockchain is another avenue to increase the confidence that what is seen on\nGitHub matches what you have downloaded. The IOTA foundation created a Github\nAction which will publish a release to their blockchain. This has shown promise,\nbut he gave a couple errors to tackle still.","url":"https://tauri.studio/docs/community/ci-cd"},{"id":"prose_docs_community_contributor_guide_md","title":"Contributor Guide","area":"community","section":"community","headings":["Contribution Flow","Hands On Example"],"subHeadings":["A Note About Contributions to the Rust Libraries"],"code":["sh","json","ini"],"text":"todo: make this friendlier and more complete Tauri is a polyglot system that\nuses: - git - Node.js - Rust - GitHub actions It can be developed on macOS,\nLinux and Windows. ## Contribution Flow 1. File an Issue 2. Fork the Repository\n3. Make Your Changes 4. Make a PR ### A Note About Contributions to the Rust\nLibraries When contributing to the Rust libraries `tauri`, `tauri-api`, and\n`tauri-updater`; you will want to setup an environment for RLS (the Rust\nLanguage Server). In the Tauri root directory, there is a `.scripts` folder that\ncontains a set of scripts to automate adding a couple temporary environment\nvariables to your shell/terminal. These environment variables point to\ndirectories in the test fixture which will prevent RLS from crashing on\ncompile-time. This is a necessary step for setting up a development environment\nfor Tauri's Rust libraries. ##### _Example Instructions_ 1. Navigate to the\nTauri Root directory. 2. Execute a script based on your Operating System from\nthis folder: `.scripts/init_env.bat` for Windows Cmd, `.scripts/init_env.ps1`\nfor Windows Powershell, `. .scripts/init_env.sh` for Linux/macOS bash (note the\nfirst `.` in this command). 3. Open your text editor/IDE from this\nshell/terminal. ## Hands On Example Let's make a new example. That's a great way\nto learn. We are going to assume you are on a nixy type of environment like\nLinux or macOS and have all of your development dependencies like rust and node\nalready sorted out. ```sh git clone git@github.com:tauri-apps/tauri.git cd\ntauri/cli/tauri.js yarn mkdir ../../examples/vanillajs && cd \"$_\" ``` ```json\n\"tauri:source\": \"node ../../../cli/tauri.js/bin/tauri\", ``` ```ini\n[dependencies.tauri] path = \"../../../../core/tauri\" features = [ \"all-api\" ]\n```","url":"https://tauri.studio/docs/community/contributor-guide"},{"id":"prose_docs_debugging_debugging_md","title":"Debugging","area":"debugging","section":"debugging","headings":["Rust Console","WebView JS Console","Create a Debug Build","Run Your App From the Terminal"],"subHeadings":[],"code":["rust","sh",null],"text":"import Alert from '@theme/Alert' import Command from '@theme/Command' With all\nthe moving pieces in Tauri, you may run into a problem that requires debugging.\nThere are a handful of locations where error details are printed, and Tauri\nincludes some tools to make the debugging process easier. ## Rust Console When\nyou run a Tauri app in development mode you will have a Rust console available.\nThis is in the terminal where you ran e.g. `tauri dev`. You can use the\nfollowing code to print something to that console from within a Rust file:\n```rust println!(\"Message from Rust: {}\", msg); ``` Sometimes you may have an\nerror in your Rust code, and the Rust compiler can give you lots of information.\nIf, for example, `tauri dev` crashes, you can rerun it like this on Linux and\nmacOS: ```sh RUST_DEBUG=1 tauri dev ``` or like this on MS Windows: ```sh set\nRUST_DEBUG=1 tauri dev ``` This will give you a granular stack trace. Generally\nspeaking, the Rust compiler will help you by giving you detailed information\nabout the issue, such as: ``` error[E0425]: cannot find value `sun` in this\nscope --> src/main.rs:11:5 | 11 | sun += i.to_string().parse::().unwrap(); | ^^^\nhelp: a local variable with a similar name exists: `sum` error: aborting due to\nprevious error For more information about this error, try `rustc --explain\nE0425`. ``` ## WebView JS Console Right click in the WebView, and choose\n`Inspect Element`. This will open up a web-inspector similar to the Chrome or\nFirefox dev tools you are used to. ## Create a Debug Build There are cases where\nyou might need to inspect the JS console in the final bundle, so Tauri provides\na simple command to create a debugging bundle: Like the normal build and dev\nprocesses, the first time you run this it will take more time than subsequent\nruns. The final bundled app will be placed in `src-tauri/target/debug/bundle`.\nThat app will ship with the development console enabled. ## Run Your App From\nthe Terminal You can also run a built app from the terminal, which will also\ngive you the Rust compiler notes (in case of errors) or your `println` messages.\nJust find the file `src-tauri/target/(release|debug)/[app name]` and either\ndouble click it (but be warned, the terminal will close on errors) or just run\nit in directly in your console.","url":"https://tauri.studio/docs/debugging/debugging"},{"id":"prose_docs_development_development_cycle_md","title":"Development Cycle","area":"development","section":"development","headings":[],"subHeadings":["1","2"],"code":[],"text":"import Alert from '@theme/Alert' import Command from '@theme/Command' ### 1.\nStart Your Devserver Now that you have everything setup, you should start your\napplication development server provided by your UI framework or bundler\n(assuming you're using one, of course). Every framework has its own development\ntooling. It is outside of the scope of this document to treat them all or keep\nthem up to date. ### 2. Start Tauri Development Window The first time you run\nthis command, it will take several minutes for the Rust package manager to\ndownload and build all the required packages. Since they are cached, subsequent\nbuilds will be much faster, as only your code will need rebuilding. Once Rust\nhas finished building, the webview will open and it should display your web app.\nYou can make changes to your web app, and if your tooling enables it, the\nwebview should update automatically just like a browser. When you make changes\nto your Rust files, they will be rebuilt automatically and your app will\nrestart. In your project repository, you SHOULD commit the\n\"src-tauri/Cargo.lock\" along with the \"src-tauri/Cargo.toml\" to git because\nCargo uses the lockfile to provide deterministic builds. As a result, it is\nrecommended that all applications check in their Cargo.lock. You SHOULD NOT\ncommit the \"src-tauri/target\" folder or any of its contents.","url":"https://tauri.studio/docs/development/development-cycle"},{"id":"prose_docs_development_security_md","title":"Security","area":"development","section":"development","headings":["Tauri Features to keep you Safer"],"subHeadings":["Secure content loading","Isolation Pattern","Tauri API"],"code":["typescript","rust","json"],"text":"import Alert from '@theme/Alert' Whether you like it or not, today's\napplications live in operating systems that can be -- and regularly are --\ncompromised by any number of attacks. When your insecure application is a\ngateway for such lateral movement into the operating system, you are\ncontributing to the tools that professional hackers have at their disposal.\nDon't be a tool. This is why we have taken every opportunity to help you secure\nyour application, prevent undesired access to system level interfaces, and\nmanufacture bullet-proof applications. Your users assume you are following best\npractices. We make that easy, but you should still read up on it below. ##\nSecurity Is A Community Responsibility (adapted from\n[Electron](https://www.electronjs.org/docs/latest/tutorial/security#security-is-everyones-responsibility))\nIt is important to remember that the security of your Tauri application is the\nresult of the overall security of Tauri itself, all Rust and NPM dependencies,\nyour code, and the devices that run the final application. The Tauri Team does\nits best to do its part, the security community does its part, and you too would\ndo well to follow a few important best practices: - **Keep your application\nup-to-date with the latest Tauri release.** When releasing your app into the\nwild, you are also shipping a bundle that has Tauri in it. Vulnerabilities\naffecting Tauri may impact the security of your application. By updating Tauri\nto the latest version, you ensure that critical vulnerabilities are already\npatched and cannot be exploited in your application. Also be sure to keep your\ncompiler (rustc) and transpilers (nodejs) up to date, because there are often\nsecurity issues that are resolved. - **Evaluate your dependencies.** While NPM\nand Crates.io provide many convenient packages, it is your responsibility to\nchoose trustworthy 3rd-party libraries - or rewrite them in Rust. If you do use\noutdated libraries affected by known vulnerabilities or are unmaintained, your\napplication security and good-night's sleep could be in jeopardy. Use tooling\nlike `npm audit` and `cargo audit` to automate this process and lean on the\nsecurity community's important work. - **Adopt more secure coding practices.**\nThe first line of defense for your application is your own code. Although Tauri\ncan protect you from common web vulnerabilities, such as Cross-Site Scripting\nbased Remote Code Execution, improper configurations can have a security impact.\nEven if this were not the case, it is highly recommended to adopt secure\nsoftware development best practices and perform security testing. We detail what\nthis means in the next section. - **Educate your Users.** True security really\nmeans that unexpected behaviour cannot happen. So in a sense, being more secure\nmeans having the peace of mind in knowing that ONLY those things that you want\nto happen can happen. In the real world, though, this is a utopian \"dream\".\nHowever, by removing as many vectors as possible and building on a solid\nfoundation, your choice for Tauri is a signal to your users that you really care\nabout them, their safety, and their devices. ## Threat Models Tauri applications\nare composed of many pieces at different points of the lifecycle. Here we\ndescribe classical threats and what you SHOULD do about them. - **Upstream\nThreats.** Tauri is a direct dependency of your project, and we maintain strict\nauthorial control of commits, reviews, pull-requests, and releases. We do our\nbest to maintain up-to-date dependencies and take action to either update or\nfork&fix. Other projects may not be so well maintained, and may not even have\never been audited. Please consider their health when integrating them, because\notherwise you may have adopted architectural debt without even knowing it. -\n**Development Threats.** We assume that you, the developer, care for your\ndevelopment environment like a shrine of purity because it is a thing of beauty.\nIt is on you to make sure that your operating system, build toolchains, and\nassociated dependencies are kept up to date. A very real risk all of us face is\nwhat is known as \"supply-chain attacks\", which are usually considered to be\nattacks on direct dependencies of your project. However, there is a growing\nclass of attacks in the wild that directly target development machines, and you\nwould be well-off to address these head-on. One practice that we highly\nrecommend, even if it is a bit more time intensive, is to only ever consume\ncritical dependencies from git using hash revisions at best or named tags as\nsecond best. This holds true for Rust as well as the Node ecosystem. Also,\nconsider requiring all contributors to sign their commits and protect GIT\nbranches and pipelines. - **Buildtime Threats.** Modern organisations use CI/CD\nto manufacture binary artifacts. At Tauri, we even provide a Github Workflow for\nbuilding on multiple platforms. If you create your own CI/CD and depend on\nthird-party tooling, be wary of actions whose versions you have not explicitly\npinned. You should sign your binaries for the platform you are shipping to, and\nwhile this can be complicated and somewhat costly to setup, end-users expect\nthat your app is verifiably from you. - **Runtime Threats** We assume the\nwebview is insecure, which has led Tauri to implement several protections\nregarding webview access to system APIs in the context of loading untrusted\nuserland content. You can read more in detail below, but using the CSP will\nlockdown types of communication that the Webview can undertake. Furthermore,\nthere is a novel \"Isolation\" pattern that prevents untrusted content or scripts\nfrom accessing the API within the Webview. And please, whatever you do, DO NOT\ntrust the results of cryptography using private keys in the Webview. We gave you\nRust for a reason. - **Updater Threats** We have done our best to make shipping\nhot-updates to the app as straightforward and secure as possible. However, if\nyou lose control of the manifest server, the build server, or the binary hosting\nservice - all bets are off. If you are building your own system, consult a\nprofessional OPS architect and build it properly. ## An unsorted list of big ole\nDONT'S: - DON'T accept content over http:// or ws:// - DON'T ship an app with\nthe development console enabled - DON'T forget to [read about\nXSS](https://owasp.org/www-community/attacks/xss/) - DON'T ship any kind of\nlocalhost server unless the app needs to talk to other devices - DON'T consume\nJS from a CDN without using an integrity checksum ## Security Researchers\nNothing is perfect, attack vectors will be found, and if you have found one - we\nwant to know about it. If you have a discovery, PLEASE DO NOT FILE A PUBLIC\nISSUE OR MAKE A PULL REQUEST. Please discretely reach out to a member of the\nteam via Discord or Email for verification, vulnerability acceptance, and\nremediation timeline. We believe in - and participate in - responsible\ndisclosure. At this time we do not have a bug-bounty programme in place, but are\nactively considering it. ## Tauri Features to keep you Safer ### Secure content\nloading Tauri restricts the [Content Security Policy\n(CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) of your HTML\npages. Local scripts are hashed, styles and external scripts are referenced\nusing a cryptographic nonce, which prevents unallowed content from being loaded.\nThe CSP protection is only enabled if\n[`tauri.security.csp`](/docs/api/config/#tauri.security.csp) is set on the Tauri\nconfiguration file. You should make it as restricted as possible, only allowing\nthe webview to load assets from hosts you trust and preferably own. At compile\ntime, Tauri appends its nonces and hashes to the relevant CSP attributes\nautomatically, so you only need to worry about what is unique to your\napplication. See script-src\n[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src],\nstyle-src\n[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src]\nand CSP Sources\n[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources]\nfor more information about this protection. With the CSP protection enabled,\nusing inline `style` attributes it not allowed. Avoid loading remote content\nsuch as scripts served over a CDN as they introduce an attack vector, but any\nuntrusted file can introduce new and subtle attack vectors. ### Isolation\nPattern The [Isolation pattern](../architecture/patterns/isolation.md) is a way\nto inject a secondary, ideally minimal, JavaScript application in between your\nfrontend application and Tauri Core. This minimal Isolation application can then\nbe used to securely verify and modify IPC messages before they reach Tauri Core.\n[The Isolation pattern guide](../architecture/patterns/isolation.md) has more\ninformation. ### Tauri API The [Tauri\nAPI](https://www.npmjs.com/package/@tauri-apps/api) provides functions to access\ncommon native functionality such as filesystem access, HTTP requests, system\nnotifications and child processes usage. They provide an easy path to JavaScript\ndevelopers to access the operating system, but they should be used carefully.\n#### Prefer specific commands When accessing a native API, you should prefer\nwriting a dedicated command to implement your business logic instead of writing\neverything on the frontend layer. For instance, see the following frontend API\nusage: ```typescript import { writeFile, Dir } from '@tauri-apps/api/fs' await\nwriteFile({ path: 'report.txt', contents: 'the file content' }, { dir: Dir.App,\n}) ``` If you do not enable the [isolation pattern](#Isolation-pattern), an\nattacker with remote code execution can overwrite the contents of `report.txt`\nsince that API is generic and enabled. If you use a dedicated command, this is\nnot an issue: ```rust #[tauri::command] async fn write_report(app:\ntauri::AppHandle) -> Result<(), String> { let app_dir =\napp.path_resolver().app_dir().expect(\"failed to get app dir\"); let report_path =\napp_dir.join(\"report.txt\"); std::fs::write(&report_path, \"the file content\")\n.map_err(|e| e.to_string()); Ok(()) } fn main() { tauri::Builder::default()\n.invoke_handler(tauri::generate_handler![write_report])\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ```typescript import { invoke } from\n'@tauri-apps/api/tauri' await invoke('write_report') ``` This example command\nwritten on the backend cannot be exploited. Tauri recommends using the webview\nas only a user interface layer, keeping important logic on the core layer. ####\nThe allowlist When using the API package, you **must** enable only the\ninterfaces your application is using. See [the allowlist\nconfiguration](/docs/api/config/#tauri.allowlist) for options to restrict which\nAPIs are enabled. This not only reduces surface area, but also treeshakes out\nunneeded functionality -- which reduces final binary size. #### API scoping Some\nAPI modules provides a configuration to scope the API access and restrict the\nsystem resources accessed. ##### Filesystem You can restrict the folders and\nfiles that can be accessed when using the `fs` module. The scope array lists\nwhat paths are allowed using glob patterns and predefined variables that\nresolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`,\n`$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`,\n`$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`,\n`$RESOURCE`, `$APP` and `$CWD`. ```json { \"tauri\": { \"allowlist\": { \"fs\": {\n\"scope\": [\"$APP/db/*\", \"$RESOURCE/check.png\"] } } } } ``` ###### Asset protocol\nYou can restrict the folders and files that can be accessed when using the\n`asset` protocol. The scope array has the same syntax as the `fs` scope array:\n```json { \"tauri\": { \"allowlist\": { \"path\": { \"all\": true }, \"protocol\": {\n\"asset\": true, \"assetScope\": ['$APP/assets/*'] } } } } ``` ```typescript import\n{ appDir, join } from '@tauri-apps/api/path' import { convertFileSrc } from\n'@tauri-apps/api/tauri' const appDirPath = await appDir() // this path is\nallowed - is matches $APP/assets/* // you can use this on tags or window.fetch()\ncalls const allowedPath = convertFileSrc(await join(appDirPath, 'assets',\n'tauri.mp4')) // this path is not allowed - it does not match $APP/assets/*\nconst disallowedPath = convertFileSrc(await join(appDirPath, 'tauri.mp4')) ```\n###### HTTP You can restrict the URLs and paths that can be accessed when using\nthe `http` module: ```json { \"tauri\": { \"allowlist\": { \"http\": { \"scope\":\n[\"https://api.github.com/repos/tauri-apps/*\"] } } } } ``` ```typescript import {\nfetch } from '@tauri-apps/api/http' // this promise is resolved await\nfetch('https://api.github.com/repos/tauri-apps/tauri') // this promise is\nrejected - the URL is not allowed on the scope await\nfetch('https://api.github.com/repos/electron/electron') ``` ###### Shell To\nprevent unrestricted access to process spawning, Tauri offers a configuration to\ndefine programs and command line arguments that are allowed to be used. While it\ncan make userland ergonomics less simple, is good security hygiene to lock down\nshell commands from spawning other, unexpected commands. ```json { \"tauri\": {\n\"allowlist\": { \"shell\": { \"scope\": [ { \"name\": \"install-dep\", \"cmd\": \"apt-get\",\n\"args\": [ \"install\", { \"validator\": \"(gcc|rustc)$\" } ] } ], // allows using the\n`open` API only using arguments that match this regex // `true` is also a valid\nvalue, which defines the regex as `https?://`. \"open\":\n\"^https://github.com/tauri-apps/\" } } } } ``` ```typescript import { Command,\nopen } from '@tauri-apps/api/shell' // this command is allowed new\nCommand('install-dep', ['install', 'rustc']).spawn() // this command is not\nfound - does not match the `name` value of the scope definition new\nCommand('install-my-dep', ['install', 'rustc']).spawn() // this command is\nrejected - does not match validator regex for the second argument new\nCommand('install-dep', ['install', 'tar']).spawn() // this command is rejected -\nextra argument new Command('install-dep', ['install', 'rustc', '-y']).spawn() //\nthis open() usage is allowed because it matches the `open` regex await\nopen('https://github.com/tauri-apps/tauri') // this open() call is rejected -\ndoes not match validator regex open('https://docs.rs/tauri/latest/tauri') ```","url":"https://tauri.studio/docs/development/security"},{"id":"prose_docs_development_updating_dependencies_md","title":"Updating Dependencies","area":"development","section":"development","headings":["Automatic updates","Manual updates"],"subHeadings":["Update NPM Packages"],"code":[],"text":"import Alert from '@theme/Alert' Especially during the alpha and beta phases,\nyou are expected to keep all Tauri dependencies and toolchains up to date. There\nis no support for any versions other than latest. ## Automatic updates The Tauri\nJS CLI has a command to install and update all needed dependencies, just run\n`tauri deps install` or `tauri deps update`. ## Manual updates ### Update NPM\nPackages If you are using the `tauri` package: ```bash $ yarn upgrade\n@tauri-apps/cli @tauri-apps/api --latest $ npm install @tauri-apps/cli@latest\n@tauri-apps/api@latest ``` You can also detect what the latest version of Tauri\nis on the command line, using: - `npm outdated @tauri-apps/cli` - `yarn outdated\n@tauri-apps/cli` Alternatively, if you are using the `vue-cli-plugin-tauri`\napproach: ```bash $ yarn upgrade vue-cli-plugin-tauri --latest $ npm install\nvue-cli-plugin-tauri@latest ``` ### Update Cargo Packages Go to\n`src-tauri/Cargo.toml` and change `tauri` to `tauri = { version = \"%version%\" }`\nwhere `%version%` is the version number shown above. (You can just use the\n`MAJOR.MINOR`) version, like `0.9`. Then do the following: ```bash $ cd\nsrc-tauri $ cargo update -p tauri ``` You can also run `cargo outdated -r tauri`\nto get direct information about the core library's latest version.","url":"https://tauri.studio/docs/development/updating-dependencies"},{"id":"prose_docs_distribution_linux_md","title":"Linux Application Distribution","area":"distribution","section":"distribution","headings":["Limitations","Debian","AppImage"],"subHeadings":[],"code":["json"],"text":"Tauri applications for Linux are distributed either with a [Debian\npackage](https://wiki.debian.org/Packaging) (a file with the `.deb` extension)\nor as an [AppImage](https://appimage.org/) when building using the Tauri CLI. ##\nLimitations Core libraries such as glibc frequently break compability with older\nsystems. For this reason, you must build your Tauri application using the oldest\nbase system you intend to support. A relatively old system such as Ubuntu 18.04\nis more suited than Ubuntu 21.04, as the binary compiled on Ubuntu 21.04 will\nhave a higher requirement of the glibc version, so when running on an older\nsystem you will face a runtime error like `/usr/lib/libc.so.6: version\n'GLIBC_2.33' not found`. We recommend using a Docker container or GitHub Actions\nto build your Tauri application for Linux. See the issues\n[#1355](https://github.com/tauri-apps/tauri/issues/1355) and\n[rust-lang/rust#57497](https://github.com/rust-lang/rust/issues/57497), in\naddition to the [AppImage\nguide](https://docs.appimage.org/reference/best-practices.html#binaries-compiled-on-old-enough-base-system)\nfor more information. ## Debian The stock Debian package generated by the Tauri\nbundler has everything you need to ship your application to Debian-based Linux\ndistributions, defining your application's icons, generating a Desktop file and\nspecifying the dependencies `libwebkit2gtk-4.0-37` and `libgtk-3-0`, along with\n`libappindicator3-1` if your app uses the system tray. If you need extended\ncontrol over the Debian package, you can provide a list of folders or files to\nmove to the package. The configuration object maps the path in the Debian\npackage to the path to the file on your filesystem, relative to the core binary\ncrate folder (`./src-tauri` by default). Here's an example configuration:\n```json { \"tauri\": { \"bundle\": { \"deb\": { \"files\": { \"usr/share/my-app\":\n\"../assets/\", // copy the entire assets directory to /usr/share/my-app\n\"/usr/share/doc/my-app/README.md\": \"../README.md\", // copy a single file } } } }\n} ``` ## AppImage AppImage is a distribution format that does not rely on the\nsystem installed packages and instead bundles all dependencies and files needed\nby the application. For this reason, the output file is larger but easier to\ndistribute since it is supported on many Linux distributions and can be executed\nwithout installation, just making the file executable (`$ chmod a+x\nMyProject.AppImage`) and running it (`./MyProject.AppImage`). AppImages are\nconvenient, simplifying the distribution process if you cannot make a package\ntargeting the distribution's package manager, but you should carefully use it as\nthe file size grows from the 2-6MBs range to 70+MBs.","url":"https://tauri.studio/docs/distribution/linux"},{"id":"prose_docs_distribution_macos_md","title":"macOS Application Distribution","area":"distribution","section":"distribution","headings":["Binary targets","Application bundle customization","Code signing and notarization"],"subHeadings":[],"code":[],"text":"Tauri applications for macOS are distributed either with an [Application\nBundle](https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html)(`.app`\nfiles) or an Apple Disk Image (`.dmg` files). The Tauri CLI automatically\nbundles your application code in these formats, providing options to code sign\nand notarize your application. ## Binary targets You can compile your\napplication targeting Apple Silicon, Intel-based Mac computers or universal\nmacOS binaries. By default, the CLI builds a binary targetting your machine's\narchitecture, but if you are using an Apple Silicon macOS you can compile Intel\nand universal binaries using the `target` option: - `tauri build --target\naarch64-apple-darwin`: targets Apple Silicon for your application; - `tauri\nbuild --target x86_64-apple-darwin`: targets Intel-based Mac computers; - `tauri\nbuild --target universal-apple-darwin`: targets [universal macOS\nbinaries](https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary).\n:::caution - Apple Silicon binaries only runs on Mac computers with Apple\nSilicon. - Intel-based binaries only runs on Intel-based Mac computers and on\nApple Silicion computers under the Rosetta translation. - Universal macOS\nbinaries runs on both architectures. ::: ## Application bundle customization The\nTauri configuration file provides the following options to customize your\napplication bundle: - **Bundle name**:\n[`package.productName`](/docs/api/config/#package.productName). - **Bundle\nversion**: [`package.version`](/docs/api/config/#package.version). -\n**Application category**:\n[`tauri.bundle.category`](/docs/api/config/#tauri.bundle.category). -\n**Copyright**:\n[`tauri.bundle.copyright`](/docs/api/config/#tauri.bundle.copyright). - **Bundle\nicon**: first `.icns` file listed on the\n[`tauri.bundle.icon`](/docs/api/config/#tauri.bundle.icon) array. - **Minimum\nsystem version**:\n[`tauri.bundle.macOS.minimumSystemVersion`](/docs/api/config/#tauri.bundle.macOS.minimumSystemVersion).\n- DMG license file**:\n[`tauri.bundle.macOS.license`](/docs/api/config/#tauri.bundle.macOS.license). -\n[**Entitlements.plist\nfile**](https://developer.apple.com/documentation/bundleresources/entitlements):\n[`tauri.bundle.macOS.entitlements`](/docs/api/config/#tauri.bundle.macOS.entitlements).\n- **Exception domain**: an insecure domain that your application can access such\nas a `localhost` or a remote `http` domain. It is a convenience configuration\naround `NSAppTransportSecurity > NSExceptionDomains` setting\n`NSExceptionAllowsInsecureHTTPLoads` and `NSIncludesSubdomains` to true. See\n[`tauri.bundle.macOS.exceptionDomain`](/docs/api/config/#tauri.bundle.macOS.exceptionDomain).\n- **Bootstrapper**: Instead of launching the app directly, you can configure the\nbundled app to run a script that tries to expose the environment variables to\nthe app; without that you'll have trouble using system programs because the\n`PATH` environment variable isn't correct. Enable it with\n[`tauri.bundle.macOS.useBootstrapper`](/docs/api/config#tauri.bundle.deb.useBootstrapper).\n:::note These options generate the application bundle [Info.plist\nfile](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html).\nYou can extend the generated file with your own `Info.plist` file stored on the\nTauri folder (`src-tauri` by default). The CLI will merge both `.plist` files on\nproduction, and the core layer will embed it on the binary on development. :::\n## Code signing and notarization See the [Code signing guide](./sign-macos.md).","url":"https://tauri.studio/docs/distribution/macos"},{"id":"prose_docs_distribution_publishing_md","title":"App Publishing","area":"distribution","section":"distribution","headings":[],"subHeadings":["1","2"],"code":[],"text":"import Alert from '@theme/Alert' import Command from '@theme/Command' ### 1.\nBuild Your Web App Now that you are ready to package your project, you will need\nto run your framework's or bundler's build command (assuming you're using one,\nof course). Every framework has its own publishing tooling. It is outside of the\nscope of this document to treat them all or keep them up to date. ### 2. Bundle\nyour application with Tauri This command will embed your web assets into a\nsingle binary with your Rust code. The binary itself will be located in\n`src-tauri/target/release/[app name]`, and installers will be located in\n`src-tauri/target/release/bundle/`. Like the `tauri dev` command, the first time\nyou run this, it will take some time to collect the Rust crates and build\neverything - but on subsequent runs it will only need to rebuild your code,\nwhich is much quicker.","url":"https://tauri.studio/docs/distribution/publishing"},{"id":"prose_docs_distribution_sign_macos_md","title":"Code Signing macOS Applications","area":"distribution","section":"distribution","headings":["Requirements","tl","Signing Tauri apps"],"subHeadings":["Creating a signing certificate","Downloading a certificate","Signing the Tauri application","Building the application","Example"],"code":["yml"],"text":"import Alert from '@theme/Alert' This guide provides information on code signing\nand notarization for macOS applications. If you are not utilizing GitHub Actions\nto perform builds of OSX DMGs, you will need to ensure the environment variable\nCI=true exists. For more information refer to Issue #592\n[https://github.com/tauri-apps/tauri/issues/592]. ## Requirements - Xcode 11 or\nabove. - An Apple Developer account enrolled to the [Apple Developer\nProgram](https://developer.apple.com/programs/). ## tl;dr The Tauri code signing\nand notarization process is configured through the following environment\nvariables: - `APPLE_SIGNING_IDENTITY`: the name of the keychain entry that\ncontains the signing certificate. - `APPLE_CERTIFICATE`: base64 string of the\n`.p12` certificate, exported from the keychain. Useful if you don't have the\ncertificate on the keychain (e.g. CI machines). - `APPLE_CERTIFICATE_PASSWORD`:\nthe password for the `.p12` certificate. - `APPLE_ID` and `APPLE_PASSWORD`: your\nApple account email and an [app-specific\npassword](https://support.apple.com/en-ca/HT204397). Only required to notarize\nthe app. - `APPLE_API_ISSUER` and `APPLE_API_KEY`: authentication with an App\nStore Connect API key instead of the Apple ID. Only required to notarize the\napp. ## Signing Tauri apps The first step to sign a macOS application is getting\na signing certificate from the Apple Developer Program. ### Creating a signing\ncertificate To create a new signing certificate you must generate a Certificate\nSigning Request (CSR) file from your Mac computer. [This\nguide](https://help.apple.com/developer-account/#/devbfa00fef7) describes the\nprocess to create a CSR. On your Apple Developer account, navigate to the\n[Certificates, IDs & Profiles\npage](https://developer.apple.com/account/resources/certificates/list) and click\non the `Add` button to open the interface to create a new certificate. Choose\nthe appropriate certificate type (`Apple Distribution` to submit apps to the App\nStore, and `Developer ID Application` to ship apps outside of the App Store).\nUpload your CSR and the certificate will be created. Only the Apple Developer\n`Account Holder` can create Developer ID Application certificates, but it can be\nassociated to a different Apple ID by creating a CSR with a different user email\naddress. ### Downloading a certificate On [Certificates, IDs & Profiles\npage](https://developer.apple.com/account/resources/certificates/list), click on\nthe certificate you want to use and then click on the `Download` button. It will\nsave a `.cer` file that once opened, installs the certificate on the keychain.\nThe name of the keychain entry represents the `signing identity`, which can also\nbe found by executing `$ security find-identity -v -p codesigning`. A signing\ncertificate is only valid if associated with your Apple ID. An invalid\ncertificate won't be listed on the Keychain Access > My Certificates tab or the\n$ security find-identity -v -p codesigning output. ### Signing the Tauri\napplication The signing configuration is provided to the Tauri bundler via\nenvironment variables. You will need to configure the certificate to use and an\noptional authentication configuration to notarize the application. ####\nCertificate environment variables - `APPLE_SIGNING_IDENTITY`: this is the\n`signing identity` we highlighted above. It must be defined to sign apps both\nlocally and on CI machines. Additionally, to simplify the process of code\nsigning on CI, Tauri can install the certificate on the keychain for you if you\ndefine the `APPLE_CERTIFICATE` and `APPLE_CERTIFICATE_PASSWORD` environment\nvariables. 1. Open the `Keychain Access` app and find your certificate's\nkeychain entry. 2. Expand the entry, double click on the key item and select\n`Export \"$KEYNAME\"`. 3. Select the path to save the `.p12` file and define the\nexported certificate password. 4. Convert the `.p12` file to base64 running the\nfollowing script on the terminal: `openssl base64 -in /path/to/certificate.p12\n-out certificate-base64.txt`. 5. Set the contents of the\n`certificate-base64.txt` file to the `APPLE_CERTIFICATE` environment variable.\n6. Set the certificate password to the `APPLE_CERTIFICATE_PASSWORD` environment\nvariable. #### Authentication environment variables These variables are only\nrequired to notarize the application. Notarization is required when using a\nDeveloper ID Application certificate. - `APPLE_ID` and `APPLE_PASSWORD`: to\nauthenticate with your Apple ID, set the `APPLE_ID` to your Apple account email\n(example: `export APPLE_ID=tauri@icloud.com`) and the `APPLE_PASSWORD` to an\n[app-specific password](https://support.apple.com/en-ca/HT204397) for the Apple\naccount. - `APPLE_API_ISSUER` and `APPLE_API_KEY`: alternatively, you can\nauthenticate using an App Store Connect API key. Open the App Store Connect's\n[Users and Access page](https://appstoreconnect.apple.com/access/users), select\nthe `Keys` tab and click on the `Add` button; select a name and the `Developer`\naccess. The `APPLE_API_ISSUER` (`Issuer ID`) is presented above the keys table,\nand the `APPLE_API_KEY` is the value on the `Key ID` column on that table. You\nalso need to download the private key, which can only be done once and is only\nvisible after a page reload (the button is shown on the table row for the newly\ncreated key). The private key file must be saved on `./private_keys`,\n`~/private_keys`, `~/.private_keys` or `~/.appstoreconnect/private_keys`, as\nstated on the `$ xcrun altool --help` command. ### Building the application With\nall these environment variables set, the Tauri bundler will automatically sign\nand notarize your application when you run the `tauri build` command. ###\nExample The following example uses GitHub Actions to sign an application using\nthe [Tauri action](https://github.com/tauri-apps/tauri-action). On GitHub, we\nfirst define the environment variables we listed above as GitHub Secrets. You\ncan view this guide\n[https://docs.github.com/en/actions/reference/encrypted-secrets] to learn about\nGitHub secrets. Once we have established the GitHub Secrets we will create a\nGitHub publish workflow in `.github/workflows/main.yml`: ```yml name: \"publish\"\non: push: branches: - release jobs: publish-tauri: strategy: fail-fast: false\nmatrix: platform: [macos-latest] runs-on: ${{ matrix.platform }} steps: - uses:\nactions/checkout@v2 - name: setup node uses: actions/setup-node@v2 with:\nnode-version: 12 - name: install Rust stable uses: actions-rs/toolchain@v1 with:\ntoolchain: stable - name: install app dependencies and build it run: yarn &&\nyarn build - uses: tauri-apps/tauri-action@v0 env: GITHUB_TOKEN: ${{\nsecrets.GITHUB_TOKEN }} ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}\nAPPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE_PASSWORD:\n${{ secrets.APPLE_CERTIFICATE_PASSWORD }} APPLE_SIGNING_IDENTITY: ${{\nsecrets.APPLE_IDENTITY_ID }} APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_PASSWORD:\n${{ secrets.APPLE_PASSWORD }} with: tagName: app-v__VERSION__ # the action\nautomatically replaces \\_\\_VERSION\\_\\_ with the app version releaseName: \"App\nv__VERSION__\" releaseBody: \"See the assets to download this version and\ninstall.\" releaseDraft: true prerelease: false ``` The workflow pulls the\nsecrets from GitHub and define them as environment variables before building the\napplication using the Tauri action. The output is a GitHub release with the\nsigned and notarized macOS application.","url":"https://tauri.studio/docs/distribution/sign-macos"},{"id":"prose_docs_distribution_sign_windows_md","title":"Windows - Code signing guide locally & with Github Actions","area":"distribution","section":"distribution","headings":["A","B","C","GitHub Secrets","Workflow Modifications"],"subHeadings":[],"code":[null],"text":"import Alert from '@theme/Alert' # Intro Code-signing will add a level of\nauthenticity to your application, while it is not required it can often improve\nthe user experience for your users. # Prerequisites - Windows - you can likely\nuse other platforms, but this tutorial is using Powershell native features. -\nCode signing certificate - you can aqquire one of these on services such as\nDigicert.com, Comodo.com, & Godaddy.com. In this guide we are using Comodo.com -\nA working tauri application # Getting Started There are a few things we will\nhave to do to get our windows installation prepared for code signing. This\nincludes converting our certificate to a speific format, installing this\ncertificate, & then decoding required information from certificate that is\nrequired by tauri. ## A. Convert your `.cer` to `.pfx` 1. You will need the\nfollowing: - certificate file (mine is `cert.cer`) - private key file (mine is\n`private-key.key`) 2. Open up a command prompt and change to your current\ndirectory using `cd Documents/Certs` 3. Convert your `.cer` to a `.pfx` using\n`openssl pkcs12 -export -in cert.cer -inkey private-key.key -out\ncertificate.pfx` 4. You will be prompted to enter an export password **DON'T\nFORGET IT!** ## B. Import your `.pfx` file into the keystore. We will now need\nto import our `.pfx` file. 1. Assign your export password to a variable using\n`$WINDOWS_PFX_PASSWORD = 'MYPASSWORD'` 2. Now Import the certificate using\n`Import-PfxCertificate -FilePath Certs/certificate.pfx -CertStoreLocation\nCert:\\CurrentUser\\My -Password (ConvertTo-SecureString -String\n$env:WINDOWS_PFX_PASSWORD -Force -AsPlainText)` ## C. Prepare Variables 1. We\nwill need the SHA-1 thumbprint of the certificate, you can get this using\n`openssl pkcs12 -info -in certificate.pfx` and look under for following ``` Bag\nAttributes localKeyID: A1 B1 A2 B2 A3 B3 A4 B4 A5 B5 A6 B6 A7 B7 A8 B8 A9 B9 A0\nB0 ``` 2. You will capture the `localKeyID` but with no spaces, in this example\nit would be `A1B1A2B2A3B3A4B4A5B5A6B6A7B7A8B8A9B9A0B0`. This is our\n`certificateThumbprint`. 3. We will need the SHA digest algorythm used for your\ncertificate (Hint: this is likely `sha256` 4. We will also need a timestamp url,\nthis is a time server used to verify the time of the certificate signing. Im\nusing `http://timestamp.comodoca.com` but whoever you got your certificate from\nlikely has one aswell. # Prepare `tauri.conf.json` file 1. Now that we have our\n`certificateThumbprint`, `digestAlgorithm`, & `timestampUrl` we will open up the\n`tauri.conf.json`. 2. In the `tauri.conf.json` you will look for the `tauri` ->\n`bundle` -> `windows` section. You will see there are three variable for the\ninformation we have captured. Fill it out like below. ``` \"windows\": {\n\"certificateThumbprint\": \"A1B1A2B2A3B3A4B4A5B5A6B6A7B7A8B8A9B9A0B0\",\n\"digestAlgorithm\": \"sha256\", \"timestampUrl\": \"http://timestamp.comodoca.com\" }\n``` 3. Save, and run `yarn | yarn build` 4. In the console output you will see\nthe following output. ``` info: signing app info: running signtool \"C:\\\\Program\nFiles (x86)\\\\Windows Kits\\\\10\\\\bin\\\\10.0.19041.0\\\\x64\\\\signtool.exe\" info: \"Done\nAdding Additional Store\\r\\nSuccessfully signed: APPLICATION FILE PATH HERE ```\nwhich shows you have successfully signed the `.exe`. And thats it! You have\nsuccessfully signed your .exe file. # BONUS: Sign your application with GitHub\nActions. We can also create a workflow to sign the application with GitHub\nactions, this will help automate your Publish time. ## GitHub Secrets We will\nneed to add a few GitHub secrets for the proper configuration of the GitHub\nAction. These can be named however you would like. - You can view\n[this](https://docs.github.com/en/actions/reference/encrypted-secrets) guide for\nhow to add GitHub secrets. The secrets we used are as follows | GitHub Secrets |\nValue for Variable | | :---: | :---: | |WINDOWS_CERTIFICATE| Base64 encoded\nversion of your .pfx certificate, can be done using this command `certutil\n-encode certificate.pfx base64cert.txt` |\n|WINDOWS_CERTIFICATE_PASSWORD|Certificate export password used on creation of\ncertificate .pfx| ## Workflow Modifications 1. We will need to add a step in the\nworkflow to properly import the certificate into the windows environment. This\nwork flow accomplishes the following 1. Assign GitHub secrets to environment\nvariables 2. Create a new `certificate` directory 3. Import\n`WINDOWS_CERTIFICATE` into tempCert.txt 4. Use `certutil` to decode the\ntempCert.txt from base64 into a `.pfx` file. 5. Remove tempCert.txt 6. Import\nthe `.pfx` file into the Cert store of Windows & convert the\n`WINDOWS_CERTIFICATE_PASSWORD` to a secure string to be used in the import\ncommand. 2. We will be using the tauri-action publish template available\n[here](https://github.com/tauri-apps/tauri-action) ``` name: \"publish\" on: push:\nbranches: - release jobs: publish-tauri: strategy: fail-fast: false matrix:\nplatform: [macos-latest, ubuntu-latest, windows-latest] runs-on: ${{\nmatrix.platform }} steps: - uses: actions/checkout@v2 - name: setup node uses:\nactions/setup-node@v1 with: node-version: 12 - name: install Rust stable uses:\nactions-rs/toolchain@v1 with: toolchain: stable - name: install webkit2gtk\n(ubuntu only) if: matrix.platform == 'ubuntu-latest' run: | sudo apt-get update\nsudo apt-get install -y webkit2gtk-4.0 - name: install app dependencies and\nbuild it run: yarn && yarn build - uses: tauri-apps/tauri-action@v0 env:\nGITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tagName: app-v__VERSION__ # the\naction automatically replaces \\_\\_VERSION\\_\\_ with the app version releaseName:\n\"App v__VERSION__\" releaseBody: \"See the assets to download this version and\ninstall.\" releaseDraft: true prerelease: false ``` 3. Right above `-name:\ninstall app dependencies and build it` you will want to add the following step\n``` - name: import windows certificate if: matrix.platform == 'windows-latest'\nenv: WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}\nWINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} run: |\nNew-Item -ItemType directory -Path certificate Set-Content -Path\ncertificate/tempCert.txt -Value $env:WINDOWS_PFX certutil -decode\ncertificate/tempCert.txt certificate/certificate.pfx Remove-Item -path\ncertificate -include tempCert.txt Import-PfxCertificate -FilePath\ncertificate/certificate.pfx -CertStoreLocation Cert:\\CurrentUser\\My -Password\n(ConvertTo-SecureString -String $env:WINDOWS_PFX_PASSWORD -Force -AsPlainText)\n``` 4. Save, and push to your repo. 5. You workflow will now be able to import\nyour windows certificate and import it into the github runner, allowing for\nautomated code-signing!","url":"https://tauri.studio/docs/distribution/sign-windows"},{"id":"prose_docs_distribution_updater_md","title":"Updater","area":"distribution","section":"distribution","headings":["Update Requests","Built","Javascript API","Events","Update Server JSON Format","Update File JSON Format","macOS","Windows","Linux"],"subHeadings":["Initialize updater and check if a new version is available","Listen New Update Available","Emit Install and Download","Listen Install Progress"],"code":["js","json","none","bash"],"text":"# Configuration Once you have your Tauri project ready, you need to configure\nthe updater. Add this in tauri.conf.json ```json \"updater\": { \"active\": true,\n\"endpoints\": [ \"https://releases.myapp.com/{{target}}/{{current_version}}\" ],\n\"dialog\": true, \"pubkey\": \"\" } ``` The required keys are \"active\" and\n\"endpoints\", others are optional. \"active\" must be a boolean. By default, it's\nset to false. \"endpoints\" must be an array. The string `{{target}}` and\n`{{current_version}}` are automatically replaced in the URL allowing you\ndetermine [server-side](#update-server-json-format) if an update is available.\nIf multiple endpoints are specified, the updater will fallback if a server is\nnot responding within the pre-defined timeout. \"dialog\" if present must be a\nboolean. By default, it's set to true. If enabled, [events](#events) are\nturned-off as the updater will handle everything. If you need the custom events,\nyou MUST turn off the built-in dialog. \"pubkey\" if present must be a valid\npublic-key generated with Tauri cli. See [Signing updates](#signing-updates). ##\nUpdate Requests Tauri is indifferent to the request the client application\nprovides for update checking. `Accept: application/json` is added to the request\nheaders because Tauri is responsible for parsing the response. For the\nrequirements imposed on the responses and the body format of an update, response\nsee [Server Support](#server-support). Your update request must *at least*\ninclude a version identifier so that the server can determine whether an update\nfor this specific version is required. It may also include other identifying\ncriteria such as operating system version, to allow the server to deliver as\nfine-grained an update as you would like. How you include the version identifier\nor other criteria is specific to the server that you are requesting updates\nfrom. A common approach is to use query parameters,\n[Configuration](#configuration) shows an example of this. ## Built-in dialog By\ndefault, updater uses a built-in dialog API from Tauri. ![New\nUpdate](https://i.imgur.com/UMilB5A.png) The dialog release notes is represented\nby the update `note` provided by the [server](#server-support). If the user\naccepts, the download and install are initialized. The user will be then\nprompted to restart the application. ## Javascript API **Attention, you need to\n_disable built-in dialog_ in your [tauri configuration](#configuration),\notherwise, events aren't emitted and the javascript API will NOT work.** ```js\nimport { checkUpdate, installUpdate } from \"@tauri-apps/api/updater\"; import {\nrelaunch } from \"@tauri-apps/api/process\"; try { const {shouldUpdate, manifest}\n= await checkUpdate(); if (shouldUpdate) { // display dialog await\ninstallUpdate(); // install complete, restart app await relaunch(); } }\ncatch(error) { console.log(error); } ``` ## Events **Attention, you need to\n_disable built-in dialog_ in your [tauri configuration](#configuration),\notherwise, events aren't emitted.** To know when an update is ready to be\ninstalled, you can subscribe to these events: ### Initialize updater and check\nif a new version is available #### If a new version is available, the event\n`tauri://update-available` is emitted. Event: `tauri://update` ### Rust ```rust\nwindow.emit(\"tauri://update\".to_string(), None); ``` ### Javascript ```js import\n{ emit } from \"@tauri-apps/api/event\"; emit(\"tauri://update\"); ``` ### Listen\nNew Update Available Event: `tauri://update-available` Emitted data: ```none\nversion Version announced by the server date Date announced by the server body\nNote announced by the server ``` ### Rust ```rust\nwindow.listen(\"tauri://update-available\".to_string(), move |msg| { println!(\"New\nversion available: {:?}\", msg); }) ``` ### Javascript ```js import { listen }\nfrom \"@tauri-apps/api/event\"; listen(\"tauri://update-available\", function (res)\n{ console.log(\"New version available: \", res); }); ``` ### Emit Install and\nDownload You need to emit this event to initialize the download and listen to\nthe [install progress](#listen-install-progress). Event:\n`tauri://update-install` ### Rust ```rust\nwindow.emit(\"tauri://update-install\".to_string(), None); ``` ### Javascript\n```js import { emit } from \"@tauri-apps/api/event\";\nemit(\"tauri://update-install\"); ``` ### Listen Install Progress Event:\n`tauri://update-status` Emitted data: ```none status [ERROR/PENDING/DONE] error\nString/null ``` PENDING is emitted when the download is started and DONE when\nthe install is complete. You can then ask to restart the application. ERROR is\nemitted when there is an error with the updater. We suggest to listen to this\nevent even if the dialog is enabled. ### Rust ```rust\nwindow.listen(\"tauri://update-status\".to_string(), move |msg| { println!(\"New\nstatus: {:?}\", msg); }) ``` ### Javascript ```js import { listen } from\n\"@tauri-apps/api/event\"; listen(\"tauri://update-status\", function (res) {\nconsole.log(\"New status: \", res); }); ``` # Server Support Your server should\ndetermine whether an update is required based on the [Update\nRequest](#update-requests) your client issues. If an update is required your\nserver should respond with a status code of [200\nOK](http://tools.ietf.org/html/rfc2616#section-10.2.1) and include the [update\nJSON](#update-server-json-format) in the body. To save redundantly downloading\nthe same version multiple times your server must not inform the client to\nupdate. If no update is required your server must respond with a status code of\n[204 No Content](http://tools.ietf.org/html/rfc2616#section-10.2.5). ## Update\nServer JSON Format When an update is available, Tauri expects the following\nschema in response to the update request provided: ```json { \"url\":\n\"https://mycompany.example.com/myapp/releases/myrelease.tar.gz\", \"version\":\n\"0.0.1\", \"notes\": \"Theses are some release notes\", \"pub_date\":\n\"2020-09-18T12:29:53+01:00\", \"signature\": \"\" } ``` The only required keys are\n\"url\" and \"version\", the others are optional. \"pub_date\" if present must be\nformatted according to ISO 8601. \"signature\" if present must be a valid\nsignature generated with Tauri cli. See [Signing updates](#signing-updates). ##\nUpdate File JSON Format The alternate update technique uses a plain JSON file\nmeaning you can store your update metadata on S3, gist, or another static file\nstore. Tauri will check against the name/version field and if the version is\nsmaller than the current one and the platform is available, the update will be\ntriggered. The format of this file is detailed below: ```json { \"name\":\"v1.0.0\",\n\"notes\":\"Test version\", \"pub_date\":\"2020-06-22T19:25:57Z\", \"platforms\": {\n\"darwin\": { \"signature\":\"\",\n\"url\":\"https://github.com/lemarier/tauri-test/releases/download/v1.0.0/app.app.tar.gz\"\n}, \"linux\": { \"signature\":\"\",\n\"url\":\"https://github.com/lemarier/tauri-test/releases/download/v1.0.0/app.AppImage.tar.gz\"\n}, \"win64\": { \"signature\":\"\",\n\"url\":\"https://github.com/lemarier/tauri-test/releases/download/v1.0.0/app.x64.msi.zip\"\n} } } ``` # Bundler (Artifacts) The Tauri bundler will automatically generate\nupdate artifacts if the updater is enabled in `tauri.conf.json` If the bundler\ncan locate your private and pubkey, your update artifacts will be automatically\nsigned. The signature can be found in the `sig` file. The signature can be\nuploaded to GitHub safely or made public as long as your private key is secure.\nYou can see how it's [bundled with the\nCI](https://github.com/tauri-apps/tauri/blob/5b6c7bb6ee3661f5a42917ce04a89d94f905c949/.github/workflows/artifacts-updater.yml#L44)\nand a [sample\ntauri.conf.json](https://github.com/tauri-apps/tauri/blob/5b6c7bb6ee3661f5a42917ce04a89d94f905c949/examples/updater/src-tauri/tauri.conf.json#L52)\n## macOS On MACOS we create a .tar.gz from the whole application. (.app) ```none\ntarget/release/bundle └── osx └── app.app └── app.app.tar.gz (update bundle) └──\napp.app.tar.gz.sig (if signature enabled) ``` ## Windows On Windows we create a\n.zip from the MSI, when downloaded and validated, we run the MSI install.\n```none target/release └── app.x64.msi └── app.x64.msi.zip (update bundle) └──\napp.x64.msi.zip.sig (if signature enabled) ``` ## Linux On Linux, we create a\n.tar.gz from the AppImage. ```none target/release/bundle └── appimage └──\napp.AppImage └── app.AppImage.tar.gz (update bundle) └── app.AppImage.tar.gz.sig\n(if signature enabled) ``` # Signing updates We offer a built-in signature to\nensure your update is safe to be installed. To sign your updates, you need two\nthings. The *Public-key* (pubkey) should be added inside your `tauri.conf.json`\nto validate the update archive before installing. The *Private key* (privkey) is\nused to sign your update and should NEVER be shared with anyone. Also, if you\nlost this key, you'll NOT be able to publish a new update to the current user\nbase (if pubkey is set in tauri.conf.json). It's important to save it at a safe\nplace and you can always access it. To generate your keys you need to use the\nTauri cli. ```bash tauri sign -g -w ~/.tauri/myapp.key ``` You have multiple\noptions available ```bash Tauri updates signer. USAGE: tauri sign [FLAGS]\n[OPTIONS] FLAGS: --force Overwrite private key even if it exists on the\nspecified path -g, --generate Generate keypair to sign files -h, --help Prints\nhelp information --no-password Set empty password for your private key -V,\n--version Prints version information OPTIONS: -p, --password Set private key\npassword when signing -k, --private-key Load the private key from a string -f,\n--private-key-path Load the private key from a file --sign-file Sign the\nspecified file -w, --write-keys Write private key to a file ``` *** Environment\nvariables used to sign with the Tauri `bundler`: If they are set, and\n`tauri.conf.json` expose the public key, the bundler will automatically generate\nand sign the updater artifacts. `TAURI_PRIVATE_KEY` Path or String of your\nprivate key `TAURI_KEY_PASSWORD` Your private key password (optional)","url":"https://tauri.studio/docs/distribution/updater"},{"id":"prose_docs_getting_started_beginning_tutorial_md","title":"Your First Tauri App","area":"getting-started","section":"getting-started","headings":["Vue CLI Plugin Tauri"],"subHeadings":["1","1","2","3","Recipes"],"code":["bash","sh",null],"text":"import Alert from '@theme/Alert' import Command from '@theme/Command' import\nLink from '@docusaurus/Link' :::caution You must have completed all the steps\nrequired for setting up the development environment on your machine. If you\nhaven't done this yet, please see the [setup page for your operating\nsystem](/docs/getting-started/prerequisites). ::: There are two ways to\nintegrate with Tauri depends on your need: - [Start a new Tauri\nproject](#1-start-a-new-tauri-project) - Or [add Tauri to existing\nproject](#1-add-tauri-to-existing-project) ### 1. Start a New Tauri Project\n```bash yarn create tauri-app #OR npx create-tauri-app ``` Just follow the\ninstructions and choose the web frontend framework you prefer.\n`create-tauri-app` will create a template project depends on your inputs. You\ncan go straight to [check `tauri\ninfo`](#3-check-tauri-info-to-make-sure-everything-is-set-up-properly) after\nthis. ### 1. Add Tauri to Existing Project: The Tauri CLI tool helps you build\nyour project, so install it at first. You can install Tauri CLI [using\n`Node.js`](#install-tauri-cli-package-as-a-dev-dependency) or [using\n`Rust`](#alternatively-install-tauri-cli-as-a-cargo-subcommand) #### Install\nTauri CLI package as a dev dependency: ```bash cd project-folder # Not required\nif you already have a package.json: # yarn init # OR # npm init yarn add -D\n@tauri-apps/cli # OR npm install -D @tauri-apps/cli ``` :::note You can install\nTauri as both a local and a global dependency, but we recommend installing it\nlocally. ::: If you decide to use Tauri as a local package with npm (not yarn),\nyou will have to define a custom script to your package.json: ```js\ntitle=package.json { // This content is just a sample \"scripts\": { \"tauri\":\n\"tauri\" } } ``` #### Alternatively, install Tauri CLI as a cargo subcommand:\nThis will install `tauri-cli` as a Cargo subcommand on the cargo binary folder\n(by default on `$HOME/.cargo/bin`): ```bash cargo install tauri-cli --locked\n--version ^1.0.0-rc ``` For more installation options, see [`cargo\ninstall`](https://doc.rust-lang.org/cargo/commands/cargo-install.html#description)\n#### Install Tauri API Package as a Dependency (optional): The `@tauri-apps/api`\npackage is recommended for projects using ES modules or modern build tools such\nas Webpack or Vite. It is the most secure way to access the Tauri APIs. ```bash\nyarn add @tauri-apps/api # OR npm install @tauri-apps/api ``` ### 2. Initialize\nTauri in Your App This command will place a new folder in your current working\ndirectory, `src-tauri`. ```sh └── src-tauri ├── .gitignore ├── Cargo.toml ├──\nrustfmt.toml ├── tauri.conf.json ├── icons │ ├── 128x128.png │ ├──\n128x128@2x.png │ ├── 32x32.png │ ├── Square107x107Logo.png │ ├──\nSquare142x142Logo.png │ ├── Square150x150Logo.png │ ├── Square284x284Logo.png │\n├── Square30x30Logo.png │ ├── Square310x310Logo.png │ ├── Square44x44Logo.png │\n├── Square71x71Logo.png │ ├── Square89x89Logo.png │ ├── StoreLogo.png │ ├──\nicon.icns │ ├── icon.ico │ └── icon.png └── src ├── build.rs ├── cmd.rs └──\nmain.rs ``` ### 3. Check `tauri info` to Make Sure Everything Is Set up\nProperly: Which should return something like: ``` Operating System -\nDarwin(16.7.0) - darwin/x64 Node.js environment Node.js - 12.16.3\n@tauri-apps/cli - 1.0.0-rc.0 @tauri-apps/api - 1.0.0-rc.0 Global packages npm -\n6.14.15 pnpm - Not installed yarn - 1.22.17 Rust environment rustup - 1.24.3\nrustc - 1.58.1 cargo - 1.58.0 toolchain - stable-x86_64-unknown-linux-gnu App\ndirectory structure /node_modules /src-tauri /src /public App tauri.rs -\n1.0.0-rc.0 build-type - bundle CSP - default-src 'self' distDir - ../public\ndevPath - ../public framework - Svelte bundler - Rollup ``` This information can\nbe very helpful when triaging problems. ### Recipes We've also defined prebuilt\nconfigurations called \"Recipes\". They may help you to customize Tauri to fit\nyour needs. [See more about recipes](../architecture/recipes/about-recipes.md).\n## Vue CLI Plugin Tauri If you are using Vue CLI, it is recommended to use the\nofficial [CLI plugin](https://github.com/tauri-apps/vue-cli-plugin-tauri).","url":"https://tauri.studio/docs/getting-started/beginning-tutorial"},{"id":"prose_docs_getting_started_prerequisites_md","title":"Prerequisites","area":"getting-started","section":"getting-started","headings":[],"subHeadings":[],"code":[],"text":"import OSList from '@theme/OSList' - Rust - Node (optional) - OS specific build\ntooling, eg. `build-essential`, `xcode-select` or `C++ build tools` For more\ninformation on platform-specific build tooling, see these guides to get started.\nAfter that, you'll be ready to [make your first Tauri\napp](/docs/getting-started/beginning-tutorial)!","url":"https://tauri.studio/docs/getting-started/prerequisites"},{"id":"prose_docs_getting_started_setting_up_linux_md","title":"Setting Up Linux","area":"getting-started","section":"getting-started","headings":["1","2","3","4","Continue"],"subHeadings":["Optional dependencies","Node","Optional Node","WSL Version 1","WSL Version 2"],"code":["sh","bash"],"text":"import Alert from '@theme/Alert' import Icon from '@theme/Icon' import { Intro }\nfrom '@theme/SetupDocs' import Tabs from '@theme/Tabs'; import TabItem from\n'@theme/TabItem'; ## 1. System Dependencies  ```sh $ sudo apt update && sudo apt\ninstall libwebkit2gtk-4.0-dev \\ build-essential \\ curl \\ wget \\ libssl-dev \\\nlibgtk-3-dev \\ libappindicator3-dev \\ patchelf \\ librsvg2-dev ``` ```sh $ sudo\npacman -Syu && sudo pacman -S --needed \\ webkit2gtk \\ base-devel \\ curl \\ wget \\\nopenssl \\ appmenu-gtk-module \\ gtk3 \\ libappindicator-gtk3 \\ patchelf \\ librsvg\n\\ libvips ``` ```sh $ sudo dnf check-update && sudo dnf install\nwebkit2gtk3-devel.x86_64 \\ openssl-devel \\ curl \\ wget \\ libappindicator-gtk3 \\\npatchelf \\ librsvg2-devel \\ && sudo dnf group install \"C Development Tools and\nLibraries\" ``` ### Optional dependencies: - `libappindicator`: needed to use the\nsystem tray feature. - `patchelf` and `librsvg`: needed to bundle `AppImage`. ##\n2. Node.js Runtime and Package Manager  ### Node.js (npm included) We recommend\nusing nvm to manage your Node.js runtime. It allows you to easily switch\nversions and update Node.js. ```sh $ curl -o-\nhttps://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash ``` We\nhave audited this bash script, and it does what it says it is supposed to do.\nNevertheless, before blindly curl-bashing a script, it is always wise to look at\nit first. Here is the file as a mere download link\n[https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh]. Once nvm is\ninstalled, close and reopen your terminal, then install the latest version of\nNode.js and npm: ```sh $ nvm install node --latest-npm $ nvm use node ``` If you\nhave any problems with nvm, please consult their project readme\n[https://github.com/nvm-sh/nvm]. ### Optional Node.js Package Manager You may\nwant to use an alternative to npm: - Yarn [https://yarnpkg.com/getting-started],\nis preferred by Tauri's team - pnpm [https://pnpm.js.org/en/installation] ## 3.\nRustc and Cargo Package Manager  The following command will install rustup\n[https://rustup.rs/], the official installer for Rust\n[https://www.rust-lang.org/]. ```bash $ curl --proto '=https' --tlsv1.2 -sSf\nhttps://sh.rustup.rs | sh ``` We have audited this bash script, and it does what\nit says it is supposed to do. Nevertheless, before blindly curl-bashing a\nscript, it is always wise to look at it first. Here is the file as a mere\ndownload link [https://sh.rustup.rs]. To make sure that Rust has been installed\nsuccessfully, run the following command: ```sh $ rustc --version latest update\non 2019-12-19, rust version 1.40.0 ``` You may need to restart your terminal if\nthe command does not work. ## 4. For Windows Subsystem for Linux (WSL) Users  In\norder to run a graphical application with WSL, you need to download **one** of\nthese X servers: Xming, Cygwin X, and vcXsrv. Since vcXsrv has been used\ninternally, it's the one we recommend to install. ### WSL Version 1 Open the X\nserver and then run `export DISPLAY=:0` in the terminal. You should now be able\nto run any graphical application via the terminal. ### WSL Version 2 You'll need\nto run a command that is slightly more complex than WSL 1: `export DISPLAY=$(cat\n/etc/resolv.conf | grep nameserver | awk '{print $2}'):0` and you need to add\n`-ac` to the X server as an argument. Note: if for some reason this command\ndoesn't work you can use an alternative command such as: `export DISPLAY=$(cat\n/etc/resolv.conf | grep nameserver | sed 's/.* //g'):0` or you can manually find\nthe Address using `cat /etc/resolve.conf | grep nameserver`. Don't forget that\nyou'll have to use the \"export\" command anytime you want to use a graphical\napplication, for each newly opened terminal. You can download some examples to\ntry with `sudo apt-get install x11-apps`. xeyes is always a good one. It can be\nhandy when troubleshooting WSL issues. ## Continue Now that you have set up the\nLinux-specific dependencies for Tauri, learn how to [add Tauri to your\nproject](/docs/getting-started/beginning-tutorial).","url":"https://tauri.studio/docs/getting-started/setting-up-linux"},{"id":"prose_docs_getting_started_setting_up_macos_md","title":"Setting Up macOS","area":"getting-started","section":"getting-started","headings":["1","2","3","Continue"],"subHeadings":["Node","Optional Node"],"code":["sh",null],"text":"import Alert from '@theme/Alert' import { Intro } from '@theme/SetupDocs' import\nIcon from '@theme/Icon' ## 1. System Dependencies  Make sure `xcode` is\ninstalled. ```sh $ xcode-select --install ``` ## 2. Node.js Runtime and Package\nManager  ### Node.js (npm included) We recommend using nvm to manage your\nNode.js runtime. It allows you to easily switch versions and update Node.js.\n```sh $ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh\n| bash ``` We have audited this bash script, and it does what it says it is\nsupposed to do. Nevertheless, before blindly curl-bashing a script, it is always\nwise to look at it first. Here is the file as a mere download link\n[https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh]. Once nvm is\ninstalled, close and reopen your terminal, then install the latest version of\nNode.js and npm: ```sh $ nvm install node --latest-npm $ nvm use node ``` If you\nhave any problems with nvm, please consult their project readme\n[https://github.com/nvm-sh/nvm]. ### Optional Node.js Package Manager You may\nwant to use an alternative to npm: - Yarn [https://yarnpkg.com/getting-started],\nis preferred by Tauri's team - pnpm [https://pnpm.js.org/en/installation] ## 3.\nRustc and Cargo Package Manager  The following command will install rustup\n[https://rustup.rs/], the official installer for Rust\n[https://www.rust-lang.org/]. ``` $ curl --proto '=https' --tlsv1.2 -sSf\nhttps://sh.rustup.rs | sh ``` We have audited this bash script, and it does what\nit says it is supposed to do. Nevertheless, before blindly curl-bashing a\nscript, it is always wise to look at it first. Here is the file as a mere\ndownload link [https://sh.rustup.rs]. To make sure that Rust has been installed\nsuccessfully, run the following command: ```sh $ rustc --version latest update\non 2019-12-19, rust version 1.40.0 ``` You may need to restart your terminal if\nthe command does not work. ## Continue Now that you have set up the\nmacOS-specific dependencies for Tauri, learn how to [add Tauri to your\nproject](/docs/getting-started/beginning-tutorial).","url":"https://tauri.studio/docs/getting-started/setting-up-macos"},{"id":"prose_docs_getting_started_setting_up_windows_md","title":"Setting Up Windows","area":"getting-started","section":"getting-started","headings":["1","2","3","4","Continue"],"subHeadings":["Node","Optional Node"],"code":["powershell"],"text":"import Alert from '@theme/Alert' import Icon from '@theme/Icon' import { Intro }\nfrom '@theme/SetupDocs' :::note For those using the Windows Subsystem for Linux\n(WSL) please refer to our [Linux specific\ninstructions](/docs/getting-started/setting-up-linux) instead. ::: ## 1. System\nDependencies  You'll need to install Microsoft Visual Studio C++ build tools.\nDownload the installer here\n[https://visualstudio.microsoft.com/visual-cpp-build-tools/], and then run it.\nWhen it asks you what packages you would like to install, select C++ Build Tools\nand make sure the Windows SDK is selected. This is a big download (over 1GB) and\ntakes the most time, so go grab a coffee. You may need to uninstall the 2017\nversion of the build tools if you have them. There are reports of Tauri not\nworking with both the 2017 and 2019 versions installed. ## 2. Node.js Runtime\nand Package Manager  ### Node.js (npm included) We recommend using nvm-windows\n[https://github.com/coreybutler/nvm-windows#installation--upgrades] to manage\nyour Node.js runtime. It allows you to easily switch versions and update\nNode.js. Then run the following from an Administrative PowerShell and press Y\nwhen prompted: ```powershell # BE SURE YOU ARE IN AN ADMINISTRATIVE PowerShell!\nnvm install latest nvm use {{latest}} # Replace with your latest downloaded\nversion ``` This will install the most recent version of Node.js with npm. ###\nOptional Node.js Package Manager You may want to use an alternative to npm: -\nYarn [https://yarnpkg.com/getting-started], is preferred by Tauri's team - pnpm\n[https://pnpm.js.org/en/installation] ## 3. Rustc and Cargo Package Manager  Now\nyou will need to install Rust [https://www.rust-lang.org/]. The easiest way to\ndo this is to use rustup [https://rustup.rs/], the official installer. - 64-bit\ndownload link [https://win.rustup.rs/x86_64] - 32-bit download link\n[https://win.rustup.rs/i686] Download and install the proper variant for your\ncomputer's architecture. ## 4. Install WebView2 WebView2 is pre-installed in\nWindows 11. Finally, you will need to install WebView2. The best way to do this\nis to download and run the Evergreen Bootstrapper from [this\npage](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section).\nIf you have problems of any kind after following these instructions, we\nrecommend that you reboot your computer before developing a Tauri project to\nensure that everything works as expected. ## Continue Now that you have set up\nthe Windows-specific dependencies for Tauri, learn how to [add Tauri to your\nproject](/docs/getting-started/beginning-tutorial).","url":"https://tauri.studio/docs/getting-started/setting-up-windows"},{"id":"prose_docs_guides_cli_md","title":"Making Your Own CLI","area":"guides","section":"guides","headings":["Base Configuration","Adding Arguments","Subcommands","Reading the matches","Complete documentation"],"subHeadings":["Positional Arguments","Named Arguments","Flag Arguments","Rust","JavaScript"],"code":["rust","js"],"text":"import Alert from '@theme/Alert' Tauri enables your app to have a CLI through\nclap [https://github.com/clap-rs/clap], a robust command line argument parser.\nWith a simple CLI definition in your `tauri.conf.json` file, you can define your\ninterface and read its argument matches map on JavaScript and/or Rust. ## Base\nConfiguration Under `tauri.conf.json`, you have the following structure to\nconfigure the interface: ```js title=src-tauri/tauri.conf.json { \"tauri\": {\n\"cli\": { \"description\": \"\", // command description that's shown on help\n\"longDescription\": \"\", // command long description that's shown on help\n\"beforeHelp\": \"\", // content to show before the help text \"afterHelp\": \"\", //\ncontent to show after the help text \"args\": [], // list of arguments of the\ncommand, we'll explain it later \"subcommands\": { \"subcommand-name\": { //\nconfigures a subcommand that is accessible // with `$ ./app subcommand-name\n--arg1 --arg2 --etc` // configuration as above, with \"description\", \"args\", etc.\n} } } } } ``` All JSON configurations here are just samples, many other fields\nhave been omitted for the sake of clarity. ## Adding Arguments The `args` array\nrepresents the list of arguments accepted by its command or subcommand. You can\nfind more details about the way to configure them here [/docs/api/config#tauri].\n### Positional Arguments A positional argument is identified by its position in\nthe list of arguments. With the following configuration: ```json\ntitle=src-tauri/tauri.conf.json:tauri.cli { \"args\": [ { \"name\": \"source\",\n\"index\": 1, \"takesValue\": true }, { \"name\": \"destination\", \"index\": 2,\n\"takesValue\": true } ] } ``` Users can run your app as `$ ./app tauri.txt\ndest.txt` and the arg matches map will define `source` as `\"tauri.txt\"` and\n`destination` as `\"dest.txt\"`. ### Named Arguments A named argument is a (key,\nvalue) pair where the key identifies the value. With the following\nconfiguration: ```json title=src-tauri/tauri.conf.json:tauri.cli { \"args\": [ {\n\"name\": \"type\", \"short\": \"t\", \"takesValue\": true, \"multiple\": true,\n\"possibleValues\": [\"foo\", \"bar\"] } ] } ``` Users can run your app as `$ ./app\n--type foo bar`, `$ ./app -t foo -t bar` or `$ ./app --type=foo,bar` and the arg\nmatches map will define `type` as `[\"foo\", \"bar\"]`. ### Flag Arguments A flag\nargument is a standalone key whose presence or absence provides information to\nyour application. With the following configuration: ```js\ntitle=src-tauri/tauri.conf.json:tauri.cli { \"args\": [ \"name\": \"verbose\",\n\"short\": \"v\", \"multipleOccurrences\": true ] } ``` Users can run your app as `$\n./app -v -v -v`, `$ ./app --verbose --verbose --verbose` or `$ ./app -vvv` and\nthe arg matches map will define `verbose` as `true`, with `occurrences = 3`. ##\nSubcommands Some CLI applications has additional interfaces as subcommands. For\ninstance, the `git` CLI has `git branch`, `git commit` and `git push`. You can\ndefine additional nested interfaces with the `subcommands` array: ```js\ntitle=src-tauri/tauri.conf.json:tauri { \"cli\": { ... \"subcommands\": { \"branch\":\n{ \"args\": [] }, \"push\": { \"args\": [] } } } } ``` Its configuration is the same\nas the root application configuration, with the `description`,\n`longDescription`, `args`, etc. ## Reading the matches ### Rust ```rust use\ntauri::api::cli::get_matches; fn main() { let context =\ntauri::generate_context!(); let cli_config =\ncontext.config().tauri.cli.clone().unwrap(); match get_matches(&cli_config) { //\n`matches` here is a Struct with { args, subcommand }. // `args` is `HashMap`\nwhere `ArgData` is a struct with { value, occurances }. // `subcommand` is\n`Option>` where `SubcommandMatches` is a struct with { name, matches }.\nOk(matches) => { println!(\"{:?}\", matches) } Err(_) => {} };\ntauri::Builder::default() .run(context) .expect(\"error while running tauri\napplication\"); } ``` ### JavaScript ```js import { getMatches } from\n'@tauri-apps/api/cli' getMatches().then((matches) => { // do something with the\n{ args, subcommand } matches }) ``` ## Complete documentation You can find more\nabout the CLI configuration here [/docs/api/config#tauri].","url":"https://tauri.studio/docs/guides/cli"},{"id":"prose_docs_guides_command_md","title":"Creating Rust Commands","area":"guides","section":"guides","headings":["Basic Example","Passing Arguments","Returning Data","Error Handling","Async Commands","Accessing the Window in Commands","Accessing an AppHandle in Commands","Accessing managed state","Creating Multiple Commands","Complete Example"],"subHeadings":[],"code":["rust","js"],"text":"import Alert from '@theme/Alert' Tauri provides a simple yet powerful \"command\"\nsystem for calling Rust functions from your web app. Commands can accept\narguments and return values. They can also return errors and be `async`. ##\nBasic Example Commands are defined in your `src-tauri/src/main.rs` file. To\ncreate a command, just add a function and annotate it with `#[tauri::command]`:\n```rust #[tauri::command] fn my_custom_command() { println!(\"I was invoked from\nJS!\"); } ``` You will have to provide a list of your commands to the builder\nfunction like so: ```rust // Also in main.rs fn main() {\ntauri::Builder::default() // This is where you pass in your commands\n.invoke_handler(tauri::generate_handler![my_custom_command])\n.run(tauri::generate_context!()) .expect(\"failed to run app\"); } ``` Now, you\ncan invoke the command from your JS code: ```js // With the Tauri API npm\npackage: import { invoke } from '@tauri-apps/api/tauri' // With the Tauri global\nscript, enabled when `tauri.conf.json > build > withGlobalTauri` is set to true:\nconst invoke = window.__TAURI__.invoke // Invoke the command\ninvoke('my_custom_command') ``` ## Passing Arguments Your command handlers can\ntake arguments: ```rust #[tauri::command] fn my_custom_command(invoke_message:\nString) { println!(\"I was invoked from JS, with this message: {}\",\ninvoke_message); } ``` Arguments should be passed as a JSON object with\ncamelCase keys: ```js invoke('my_custom_command', { invokeMessage: 'Hello!' })\n``` Arguments can be of any type, as long as they implement\n[serde::Deserialize](https://serde.rs/derive.html). ## Returning Data Command\nhandlers can return data as well: ```rust #[tauri::command] fn\nmy_custom_command() -> String { \"Hello from Rust!\".into() } ``` The `invoke`\nfunction returns a promise that resolves with the returned value: ```js\ninvoke('my_custom_command').then((message) => console.log(message)) ``` Returned\ndata can be of any type, as long as it implements\n[Serde::Serialize](https://serde.rs/derive.html). ## Error Handling If your\nhandler could fail and needs to be able to return an error, have the function\nreturn a `Result`: ```rust #[tauri::command] fn my_custom_command() -> Result {\n// If something fails Err(\"This failed!\".into()) // If it worked Ok(\"This\nworked!\".into()) } ``` If the command returns an error, the promise will reject,\notherwise it resolves: ```js invoke('my_custom_command') .then((message) =>\nconsole.log(message)) .catch((error) => console.error(error)) ``` ## Async\nCommands Async commands are executed on a separate thread using the async\nruntime [https://docs.rs/tauri/1.0.0-rc.0/tauri/async_runtime/fn.spawn.html].\nCommands without the async keyword are executed on the main thread, unless\ndefined with #[tauri::command(async)]. If your command needs to run\nasynchronously, simply declare it as `async`: ```rust #[tauri::command] async fn\nmy_custom_command() { // Call another async function and wait for it to finish\nlet result = some_async_function().await; println!(\"Result: {}\", result); } ```\nSince invoking the command from JS already returns a promise, it works just like\nany other command: ```js invoke('my_custom_command').then(() =>\nconsole.log('Completed!')) ``` ## Accessing the Window in Commands Commands can\naccess the `Window` instance that invoked the message: ```rust #[tauri::command]\nasync fn my_custom_command(window: tauri::Window) { println!(\"Window: {}\",\nwindow.label()); } ``` ## Accessing an AppHandle in Commands Commands can access\nan `AppHandle` instance: ```rust #[tauri::command] async fn\nmy_custom_command(app_handle: tauri::AppHandle) { let app_dir =\napp_handle.path_resolver().app_dir(); use tauri::GlobalShortcutManager;\napp_handle.global_shortcut_manager().register(\"CTRL + U\", move || {}); } ``` ##\nAccessing managed state Tauri can manage state using the `manage` function on\n`tauri::Builder`. The state can be accessed on a command using `tauri::State`:\n```rust struct MyState(String); #[tauri::command] fn my_custom_command(state:\ntauri::State) { assert_eq!(state.0 == \"some state value\", true); } fn main() {\ntauri::Builder::default() .manage(MyState(\"some state value\".into()))\n.invoke_handler(tauri::generate_handler![my_custom_command])\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ## Creating Multiple Commands The\n`tauri::generate_handler!` macro takes an array of commands. To register\nmultiple commands, you cannot call invoke_handler multiple times. Only the last\ncall will be used. You must pass each command to a single call of\n`tauri::generate_handler!`. ```rust #[tauri::command] fn cmd_a() -> String {\n\"Command a\" } #[tauri::command] fn cmd_b() -> String { \"Command b\" } fn main() {\ntauri::Builder::default() .invoke_handler(tauri::generate_handler![cmd_a,\ncmd_b]) .run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ## Complete Example Any or all of the above features can be\ncombined: ```rust title=main.rs // Definition in main.rs struct Database;\n#[derive(serde::Serialize)] struct CustomResponse { message: String, other_val:\nusize, } async fn some_other_function() -> Option { Some(\"response\".into()) }\n#[tauri::command] async fn my_custom_command( window: tauri::Window, number:\nusize, database: tauri::State<'_, Database>, ) -> Result { println!(\"Called from\n{}\", window.label()); let result: Option = some_other_function().await; if let\nSome(message) = result { Ok(CustomResponse { message, other_val: 42 + number, })\n} else { Err(\"No result\".into()) } } fn main() { tauri::Builder::default()\n.manage(Database {})\n.invoke_handler(tauri::generate_handler![my_custom_command])\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ```js // Invocation from JS invoke('my_custom_command', {\nnumber: 42, }) .then((res) => console.log(`Message: ${res.message}, Other Val:\n${res.other_val}`) ) .catch((e) => console.error(e)) ```","url":"https://tauri.studio/docs/guides/command"},{"id":"prose_docs_guides_events_md","title":"Events","area":"guides","section":"guides","headings":["Frontend","Backend"],"subHeadings":["Global events","Window","Global events","Window"],"code":["ts","rust"],"text":"The Tauri event system is a multi-producer multi-consumer communication\nprimitive that allows message passing between the frontend and the backend. It\nis analogous to the command system, but payload type check must be written on\nthe event handler and it simplifies communication from the backend to the\nfrontend, working like a channel. A Tauri application can listen and emit to\nglobal and window-specific events. Usage from the frontend and the backend are\ndescribed below. ## Frontend The event system is accessible on the frontend on\nthe `event` and `window` modules of the `@tauri-apps/api` package. ### Global\nevents To use the global event channel, import the `event` module and use the\n`emit` and `listen` functions: ```ts import { emit, listen } from\n'@tauri-apps/api/event' // listen to the `click` event and get a function to\nremove the event listener // there's also a `once` function that subscribes to\nan event and automatically unsubscribes the listener on the first event const\nunlisten = await listen('click', event => { // event.event is the event name\n(useful if you want to use a single callback fn for multiple event types) //\nevent.payload is the payload object }) // emits the `click` event with the\nobject payload emit('click', { theMessage: 'Tauri is awesome!' }) ``` ###\nWindow-specific events Window-specific events are exposed on the `window`\nmodule. ```ts import { appWindow, WebviewWindow } from '@tauri-apps/api/window'\n// emit an event that are only visible to the current window\nappWindow.emit('event', { message: 'Tauri is awesome!' }) // create a new\nwebview window and emit an event only to that window const webview = new\nWebviewWindow('window') webview.emit('event') ``` ## Backend On the backend, the\nglobal event channel is exposed on the `App` struct, and window-specific events\ncan be emitted using the `Window` trait. ### Global events ```rust use\ntauri::Manager; // the payload type must implement `Serialize`. // for global\nevents, it also must implement `Clone`. #[derive(Clone, serde::Serialize)]\nstruct Payload { message: String, } fn main() { tauri::Builder::default()\n.setup(|app| { // listen to the `event-name` (emitted on any window) let id =\napp.listen_global(\"event-name\", |event| { println!(\"got event-name with payload\n{:?}\", event.payload()); }); // unlisten to the event using the `id` returned on\nthe `listen_global` function // an `once_global` API is also exposed on the\n`App` struct app.unlisten(id); // emit the `event-name` event to all webview\nwindows on the frontend app.emit_all(\"event-name\", Payload { message: \"Tauri is\nawesome!\".into() }).unwrap(); Ok(()) }) .run(tauri::generate_context!())\n.expect(\"failed to run app\"); } ``` ### Window-specific events To use the\nwindow-specific event channel, a `Window` object can be obtained on a command\nhandler or with the `get_window` function: ```rust use tauri::{Manager, Window};\n// the payload type must implement `Serialize`. #[derive(serde::Serialize)]\nstruct Payload { message: String, } // init a background process on the command,\nand emit periodic events only to the window that used the command\n#[tauri::command] fn init_process(window: Window) { std::thread::spawn(move || {\nloop { window.emit(\"event-name\", Payload { message: \"Tauri is awesome!\".into()\n}).unwrap(); } }); } fn main() { tauri::Builder::default() .setup(|app| { //\n`main` here is the window label; it is defined on the window creation or under\n`tauri.conf.json` // the default value is `main`. note that it must be unique\nlet main_window = app.get_window(\"main\").unwrap(); // listen to the `event-name`\n(emitted on the `main` window) let id = main_window.listen(\"event-name\", |event|\n{ println!(\"got window event-name with payload {:?}\", event.payload()); }); //\nunlisten to the event using the `id` returned on the `listen` function // an\n`once` API is also exposed on the `Window` struct main_window.unlisten(id); //\nemit the `event-name` event to the `main` window main_window.emit(\"event-name\",\nPayload { message: \"Tauri is awesome!\".into() }).unwrap(); Ok(()) })\n.invoke_handler(tauri::generate_handler![init_process])\n.run(tauri::generate_context!()) .expect(\"failed to run app\"); } ```","url":"https://tauri.studio/docs/guides/events"},{"id":"prose_docs_guides_icons_md","title":"Icons","area":"guides","section":"guides","headings":[],"subHeadings":[],"code":["sh","json"],"text":"import Command from '@theme/Command' import Alert from '@theme/Alert' Tauri\nships with a default iconset based on its logo. This is probably NOT what you\nwant when you ship your application. To remedy this common situation, Tauri\nprovides the `icon` command that will take an input file (\"./app-icon.png\" by\ndefault) and create all the icons needed for the various platforms: ```sh\nOptions --help, -h Displays this message --log, l Logging [boolean] --icon, i\nSource icon (png, 1240x1240 with transparency) --target, t Target folder\n(default: 'src-tauri/icons') --compression, c Compression type\n[pngquant|optipng|zopfli] ``` These will be placed in your `src-tauri/icons`\nfolder where they will automatically be included in your built app. If you need\nto source your icons from some other location, you can edit this part of the\n`src-tauri/tauri.conf.json` file: ```json { \"tauri\": { \"bundle\": { \"icon\": [\n\"icons/32x32.png\", \"icons/128x128.png\", \"icons/128x128@2x.png\",\n\"icons/icon.icns\", \"icons/icon.ico\" ] } } } ``` - icon.icns = macOS - icon.ico =\nMS Windows - \\*.png = Linux","url":"https://tauri.studio/docs/guides/icons"},{"id":"prose_docs_guides_menu_md","title":"Window Menu","area":"guides","section":"guides","headings":[],"subHeadings":["Creating a menu","Adding the menu to all windows","Adding the menu to a specific window","Listening to events on custom menu items","Updating menu items"],"code":["rust"],"text":"Native application menus can be attached to a window. ### Creating a menu To\ncreate a native window menu, import the `Menu`, `Submenu`, `MenuItem` and\n`CustomMenuItem` types. The `MenuItem` enum contains a collection of\nplatform-specific items (currently not implemented on Windows). The\n`CustomMenuItem` allows you to create your own menu items and add special\nfunctionality to them. ```rust use tauri::{CustomMenuItem, Menu, MenuItem,\nSubmenu}; ``` Create a `Menu` instance: ```rust // here `\"quit\".to_string()`\ndefines the menu item id, and the second parameter is the menu item label. let\nquit = CustomMenuItem::new(\"quit\".to_string(), \"Quit\"); let close =\nCustomMenuItem::new(\"close\".to_string(), \"Close\"); let submenu =\nSubmenu::new(\"File\", Menu::new().add_item(quit).add_item(close)); let menu =\nMenu::new() .add_native_item(MenuItem::Copy)\n.add_item(CustomMenuItem::new(\"hide\", \"Hide\")) .add_submenu(submenu); ``` ###\nAdding the menu to all windows The defined menu can be set to all windows using\nthe `menu` API on the `tauri::Builder` struct: ```rust use\ntauri::{CustomMenuItem, Menu, MenuItem, Submenu}; fn main() { let menu =\nMenu::new(); // configure the menu tauri::Builder::default() .menu(menu)\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ### Adding the menu to a specific window You can create a\nwindow and set the menu to be used. This allows defining a specific menu set for\neach application window. ```rust use tauri::{CustomMenuItem, Menu, MenuItem,\nSubmenu}; use tauri::WindowBuilder; fn main() { let menu = Menu::new(); //\nconfigure the menu tauri::Builder::default() .create_window(\n\"main-window\".to_string(), tauri::WindowUrl::App(\"index.html\".into()), move\n|window_builder, webview_attributes| { (window_builder.menu(menu),\nwebview_attributes) }, ) .run(tauri::generate_context!()) .expect(\"error while\nrunning tauri application\"); } ``` ### Listening to events on custom menu items\nEach `CustomMenuItem` triggers an event when clicked. Use the `on_menu_event`\nAPI to handle them, either on the global `tauri::Builder` or on an specific\nwindow. #### Listening to events on global menus ```rust use\ntauri::{CustomMenuItem, Menu, MenuItem}; fn main() { let menu = vec![]; //\ninsert the menu array here tauri::Builder::default() .menu(menu)\n.on_menu_event(|event| { match event.menu_item_id() { \"quit\" => {\nstd::process::exit(0); } \"close\" => { event.window().close().unwrap(); } _ => {}\n} }) .run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` #### Listening to events on window menus ```rust use\ntauri::{CustomMenuItem, Menu, MenuItem}; use tauri::{Manager, WindowBuilder}; fn\nmain() { let menu = vec![]; // insert the menu array here\ntauri::Builder::default() .create_window( \"main-window\".to_string(),\ntauri::WindowUrl::App(\"index.html\".into()), move |window_builder,\nwebview_attributes| { (window_builder.menu(menu), webview_attributes) }, )\n.setup(|app| { let window = app.get_window(\"main-window\").unwrap(); let window_\n= window.clone(); window.on_menu_event(move |event| { match\nevent.menu_item_id().as_str() { \"quit\" => { std::process::exit(0); } \"close\" =>\n{ window_.close().unwrap(); } _ => {} } }); Ok(()) })\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ### Updating menu items The `Window` struct has a\n`menu_handle` method, which allows updating menu items: ```rust fn main() {\ntauri::Builder::default() .setup(|app| { let main_window =\napp.get_window(\"main\").unwrap(); let menu_handle = main_window.menu_handle();\nstd::thread::spawn(move || { // you can also `set_selected`, `set_enabled` and\n`set_native_image` (macOS only). menu_handle.get_item(\"item_id\").set_title(\"New\ntitle\"); }) Ok(()) }) } ```","url":"https://tauri.studio/docs/guides/menu"},{"id":"prose_docs_guides_multiwindow_md","title":"Multiwindow","area":"guides","section":"guides","headings":[],"subHeadings":[],"code":[],"text":"Manage multiple windows on a single application.","url":"https://tauri.studio/docs/guides/multiwindow"},{"id":"prose_docs_guides_plugin_md","title":"Tauri Plugins","area":"guides","section":"guides","headings":["Using a Plugin","Writing a Plugin","Writing a Plugin"],"subHeadings":["API package","Conventions","Advanced"],"code":["rust","sh","ts"],"text":"Plugins allow you to hook into the Tauri application lifecycle and introduce new\ncommands. ## Using a Plugin To use a plugin, just pass the plugin instance to\nthe App's `plugin` method: ```rust fn main() { tauri::Builder::default()\n.plugin(my_awesome_plugin::init()) .run(tauri::generate_context!())\n.expect(\"failed to run app\"); } ``` ## Writing a Plugin Plugins are reusable\nextensions to the Tauri API that solve common problems. They are also a very\nconvenient way to structure your own code base! If you intend to share your\nplugin with others, we provide a ready-made template! With the tauri-cli\ninstalled just run: ```sh tauri plugin init --name awesome ``` ### API package\nBy default consumers of your plugin can call provided commands like this: ```ts\nimport { invoke } from '@tauri-apps/api' invoke('plugin:awesome|do_something')\n``` where `awesome` will be replaced by your plugin name. This isn't very\nconvenient however, so it's common for plugins to provide a so called _API\npackage_, a JavaScript package that provides convenient access to your commands.\n> An example of this is the\n[tauri-plugin-store](https://github.com/tauri-apps/tauri-plugin-store), that\nprovides a convenient class structure to accessing a store. > You can scaffold a\nplugin with attached API package like this: ```sh tauri plugin init --name\nawesome --api ``` ## Writing a Plugin Using the `tauri::plugin::Builder` you can\ndefine plugins similar to how you define your app: ```rust use\ntauri::plugin::{Builder, TauriPlugin}; // the plugin custom command handlers if\nyou choose to extend the API. #[tauri::command] // this will be accessible with\n`invoke('plugin:awesome|initialize')`. // where `awesome` is the plugin name. fn\ninitialize() {} #[tauri::command] // this will be accessible with\n`invoke('plugin:awesome|do_something')`. fn do_something() {} pub fn init() ->\nTauriPlugin { Builder::new(\"awesome\")\n.invoke_handler(tauri::generate_handler![initialize, do_something]) .build() }\n``` Plugins can setup and maintain state, just like your app can: ```rust use\ntauri::{ AppHandle, Runtime, State plugin::{Builder, TauriPlugin} };\n#[derive(Default)] struct MyState { } #[tauri::command] // this will be\naccessible with `invoke('plugin:awesome|do_something')`. fn do_something(_app:\nAppHandle, state: State<'_, MyState>) { // you can access `MyState` here! }\nBuilder::new(\"awesome\") .invoke_handler(tauri::generate_handler![initialize,\ndo_something]) .setup(|app_handle| { // setup plugin specific state here\napp.manage(MyState::default()) Ok(()) }) .build() ``` ### Conventions - The\ncrate exports an `init` method to create the plugin. - Plugins should have a\nclear name with `tauri-plugin-` prefix. - Include `tauri-plugin` keyword in\n`Cargo.toml`/`package.json`. - Document your plugin in English. - Add an example\napp showcasing your plugin. ### Advanced Instead of relying on the\n`tauri::plugin::TauriPlugin` struct returned by `tauri::plugin::Builder::build`,\nyou can implement the `tauri::plugin::Plugin` yourself. This allows you to have\nfull control over the associated data. Note that each function on the `Plugin`\ntrait is optional, except the `name` function. ```rust use\ntauri::{plugin::{Plugin, Result as PluginResult}, Runtime, PageLoadPayload,\nWindow, Invoke, AppHandle}; struct MyAwesomePlugin { invoke_handler: Box) + Send\n+ Sync>, // plugin state, configuration fields } // the plugin custom command\nhandlers if you choose to extend the API. #[tauri::command] // this will be\naccessible with `invoke('plugin:awesome|initialize')`. // where `awesome` is the\nplugin name. fn initialize() {} #[tauri::command] // this will be accessible\nwith `invoke('plugin:awesome|do_something')`. fn do_something() {} impl\nMyAwesomePlugin { // you can add configuration fields here, // see\nhttps://doc.rust-lang.org/1.0.0/style/ownership/builders.html pub fn new() ->\nSelf { Self { invoke_handler: Box::new(tauri::generate_handler![initialize,\ndo_something]), } } } impl Plugin for MyAwesomePlugin { /// The plugin name.\nMust be defined and used on the `invoke` calls. fn name(&self) -> &'static str {\n\"awesome\" } /// The JS script to evaluate on initialization. /// Useful when\nyour plugin is accessible through `window` /// or needs to perform a JS task on\napp initialization /// e.g. \"window.awesomePlugin = { ... the plugin interface\n}\" fn initialization_script(&self) -> Option { None } /// initialize plugin with\nthe config provided on `tauri.conf.json > plugins > $yourPluginName` or the\ndefault value. fn initialize(&mut self, app: &AppHandle, config:\nserde_json::Value) -> PluginResult<()> { Ok(()) } /// Callback invoked when the\nWindow is created. fn created(&mut self, window: Window) {} /// Callback invoked\nwhen the webview performs a navigation. fn on_page_load(&mut self, window:\nWindow, payload: PageLoadPayload) {} /// Extend the invoke handler. fn\nextend_api(&mut self, message: Invoke) { (self.invoke_handler)(message) } } ```","url":"https://tauri.studio/docs/guides/plugin"},{"id":"prose_docs_guides_splashscreen_md","title":"Splashscreen","area":"guides","section":"guides","headings":[],"subHeadings":["Setup","Waiting for Webpage","Waiting for Rust"],"code":["diff",null],"text":"import Link from '@docusaurus/Link' If your webpage could take some time to\nload, or if you need to run an initialization procedure in Rust before\ndisplaying your main window, a splashscreen could improve the loading experience\nfor the user. ### Setup First, create a `splashscreen.html` in your `distDir`\nthat contains the HTML code for a splashscreen. Then, update your\n`tauri.conf.json` like so: ```diff \"windows\": [ { \"title\": \"Tauri App\", \"width\":\n800, \"height\": 600, \"resizable\": true, \"fullscreen\": false, + \"visible\": false\n// Hide the main window by default }, // Add the splashscreen window + { +\n\"width\": 400, + \"height\": 200, + \"decorations\": false, + \"url\":\n\"splashscreen.html\", + \"label\": \"splashscreen\" + } ] ``` Now, your main window\nwill be hidden and the splashscreen window will show when your app is launched.\nNext, you'll need a way to close the splashscreen and show the main window when\nyour app is ready. How you do this depends on what you are waiting for before\nclosing the splashscreen. ### Waiting for Webpage If you are waiting for your\nweb code, you'll want to create a `close_splashscreen` [command](command.md).\n```rust title=src-tauri/main.rs use tauri::Manager; // Create the command:\n#[tauri::command] fn close_splashscreen(window: tauri::Window) { // Close\nsplashscreen if let Some(splashscreen) = window.get_window(\"splashscreen\") {\nsplashscreen.close().unwrap(); } // Show main window\nwindow.get_window(\"main\").unwrap().show().unwrap(); } // Register the command:\nfn main() { tauri::Builder::default() // Add this line\n.invoke_handler(tauri::generate_handler![close_splashscreen])\n.run(tauri::generate_context!()) .expect(\"failed to run app\"); } ``` Then, you\ncan call it from your JS: ```js // With the Tauri API npm package: import {\ninvoke } from '@tauri-apps/api/tauri' // With the Tauri global script: const\ninvoke = window.__TAURI__.invoke document.addEventListener('DOMContentLoaded',\n() => { // This will wait for the window to load, but you could // run this\nfunction on whatever trigger you want invoke('close_splashscreen') }) ``` ###\nWaiting for Rust If you are waiting for Rust code to run, put it in the `setup`\nfunction handler so you have access to the `App` instance: ```rust\ntitle=src-tauri/main.rs use tauri::Manager; fn main() {\ntauri::Builder::default() .setup(|app| { let splashscreen_window =\napp.get_window(\"splashscreen\").unwrap(); let main_window =\napp.get_window(\"main\").unwrap(); // we perform the initialization code on a new\ntask so the app doesn't freeze tauri::async_runtime::spawn(async move { //\ninitialize your app here instead of sleeping :) println!(\"Initializing...\");\nstd::thread::sleep(std::time::Duration::from_secs(2)); println!(\"Done\ninitializing.\"); // After it's done, close the splashscreen and display the main\nwindow splashscreen_window.close().unwrap(); main_window.show().unwrap(); });\nOk(()) }) .run(tauri::generate_context!()) .expect(\"failed to run app\"); } ```","url":"https://tauri.studio/docs/guides/splashscreen"},{"id":"prose_docs_guides_system_tray_md","title":"System Tray","area":"guides","section":"guides","headings":[],"subHeadings":["Setup","Creating a system tray","Configuring a system tray context menu","Configure the app system tray","Listening to system tray events","Updating system tray"],"code":["json","rust"],"text":"Native application system tray. ### Setup Configure the `systemTray` object on\n`tauri.conf.json`: ```json { \"tauri\": { \"systemTray\": { \"iconPath\":\n\"icons/icon.png\", \"iconAsTemplate\": true } } } ``` The `iconPath` is pointed to\na PNG file on macOS and Linux, and a `.ico` file must exist for Windows support.\nThe `iconAsTemplate` is a boolean value that determines whether the image\nrepresents a\n[template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc)\nimage on macOS. ### Creating a system tray To create a native system tray,\nimport the `SystemTray` type: ```rust use tauri::SystemTray; ``` Initialize a\nnew tray instance: ```rust let tray = SystemTray::new(); ``` ### Configuring a\nsystem tray context menu Optionally you can add a context menu that is visible\nwhen the tray icon is right clicked. Import the `SystemTrayMenu`,\n`SystemTrayMenuItem` and `CustomMenuItem` types: ```rust use\ntauri::{CustomMenuItem, SystemTrayMenu, SystemTrayMenuItem}; ``` Create the\n`SystemTrayMenu`: ```rust // here `\"quit\".to_string()` defines the menu item id,\nand the second parameter is the menu item label. let quit =\nCustomMenuItem::new(\"quit\".to_string(), \"Quit\"); let hide =\nCustomMenuItem::new(\"hide\".to_string(), \"Hide\"); let tray_menu =\nSystemTrayMenu::new() .add_item(quit)\n.add_native_item(SystemTrayMenuItem::Separator) .add_item(hide); ``` Add the\ntray menu to the `SystemTray` instance: ```rust let tray =\nSystemTray::new().with_menu(tray_menu); ``` ### Configure the app system tray\nThe created `SystemTray` instance can be set using the `system_tray` API on the\n`tauri::Builder` struct: ```rust use tauri::{CustomMenuItem, SystemTray,\nSystemTrayMenu}; fn main() { let tray_menu = SystemTrayMenu::new(); // insert\nthe menu items here let system_tray = SystemTray::new() .with_menu(tray_menu);\ntauri::Builder::default() .system_tray(system_tray)\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ### Listening to system tray events Each `CustomMenuItem`\ntriggers an event when clicked. Also, Tauri emits tray icon click events. Use\nthe `on_system_tray_event` API to handle them: ```rust use\ntauri::{CustomMenuItem, SystemTray, SystemTrayMenu}; use tauri::Manager; fn\nmain() { let tray_menu = SystemTrayMenu::new(); // insert the menu items here\ntauri::Builder::default() .system_tray(SystemTray::new().with_menu(tray_menu))\n.on_system_tray_event(|app, event| match event { SystemTrayEvent::LeftClick {\nposition: _, size: _, .. } => { println!(\"system tray received a left click\"); }\nSystemTrayEvent::RightClick { position: _, size: _, .. } => { println!(\"system\ntray received a right click\"); } SystemTrayEvent::DoubleClick { position: _,\nsize: _, .. } => { println!(\"system tray received a double click\"); }\nSystemTrayEvent::MenuItemClick { id, .. } => { match id.as_str() { \"quit\" => {\nstd::process::exit(0); } \"hide\" => { let window =\napp.get_window(\"main\").unwrap(); window.hide().unwrap(); } _ => {} } } _ => {}\n}) .run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` ### Updating system tray The `AppHandle` struct has a\n`tray_handle` method, which returns a handle to the system tray allowing\nupdating tray icon and context menu items: #### Updating context menu items\n```rust use tauri::{CustomMenuItem, SystemTray, SystemTrayMenu}; use\ntauri::Manager; fn main() { let tray_menu = SystemTrayMenu::new(); // insert the\nmenu items here tauri::Builder::default()\n.system_tray(SystemTray::new().with_menu(tray_menu)) .on_system_tray_event(|app,\nevent| match event { SystemTrayEvent::MenuItemClick { id, .. } => { // get a\nhandle to the clicked menu item // note that `tray_handle` can be called\nanywhere, // just get a `AppHandle` instance with `app.handle()` on the setup\nhook // and move it to another function or thread let item_handle =\napp.tray_handle().get_item(&id); match id.as_str() { \"hide\" => { let window =\napp.get_window(\"main\").unwrap(); window.hide().unwrap(); // you can also\n`set_selected`, `set_enabled` and `set_native_image` (macOS only).\nitem_handle.set_title(\"Show\").unwrap(); } _ => {} } } _ => {} })\n.run(tauri::generate_context!()) .expect(\"error while running tauri\napplication\"); } ``` #### Updating tray icon Note that `tauri::Icon` must be a\n`Path` variant on Linux, and `Raw` variant on Windows and macOS. ```rust\napp.tray_handle().set_icon(tauri::Icon::Raw(include_bytes!(\"../path/to/myicon.ico\"))).unwrap();\n```","url":"https://tauri.studio/docs/guides/system-tray"},{"id":"prose_docs_guides_window_customization_md","title":"Window Customization","area":"guides","section":"guides","headings":["Configuration","Creating a Custom Titlebar"],"subHeadings":["CSS","HTML","JS"],"code":["css","html","js"],"text":"` tag: ```html\nminimize [https://api.iconify.design/mdi:window-minimize.svg]\nmaximize [https://api.iconify.design/mdi:window-maximize.svg]\nclose [https://api.iconify.design/mdi:close.svg]\n``` Note that you may need to move the rest of your content down so that the\ntitlebar doesn't cover it. ### JS Finally, you'll need to make the buttons work:\n```js import { appWindow } from '@tauri-apps/api/window' document\n.getElementById('titlebar-minimize') .addEventListener('click', () =>\nappWindow.minimize()) document .getElementById('titlebar-maximize')\n.addEventListener('click', () => appWindow.toggleMaximize()) document\n.getElementById('titlebar-close') .addEventListener('click', () =>\nappWindow.close()) ```","url":"https://tauri.studio/docs/guides/window-customization"},{"id":"prose_docs_testing_webdriver_ci_md","title":"Continuous Integration","area":"testing","section":"webdriver","headings":[],"subHeadings":[],"code":["yaml"],"text":"Utilizing Linux and some programs to create a fake display, it is possible to\nrun [WebDriver] tests with [`tauri-driver`] on your CI. The following example\nwill use the [WebdriverIO] example we [previously built together] and GitHub\nActions. This means the following assumptions: 1. The Tauri application is in\nthe repository root and the binary builds when running `cargo build --release`.\n2. The [WebDriverIO] test runner is in the `webdriver/webdriverio` directory and\nruns when `yarn test` is used in that directory. The following is a commented\nGitHub Actions workflow file at `.github/workflows/webdriver.yml` ```yaml # run\nthis action when the repository is pushed to on: [ push ] # the name of our\nworkflow name: WebDriver jobs: # a single job named test test: # the display\nname the test job name: WebDriverIO Test Runner # we want to run on the latest\nlinux environment runs-on: ubuntu-latest # the steps our job runs **in order**\nsteps: # checkout the code on the workflow runner - uses: actions/checkout@v2 #\ninstall system dependencies that Tauri needs to compile on Linux. # note the\nextra dependencies for `tauri-driver` to run which are `webkit2gtk-driver` and\n`xvfb` - name: Tauri dependencies run: >- sudo apt-get update && sudo apt-get\ninstall -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0\nlibappindicator3-dev webkit2gtk-driver xvfb # install the latest Rust stable -\nname: Rust stable uses: actions-rs/toolchain@v1 with: toolchain: stable # we run\nour rust tests before the webdriver tests to avoid testing a broken application\n- name: Cargo test uses: actions-rs/cargo@v1 with: command: test # build a\nrelease build of our application to be used during our WebdriverIO tests - name:\nCargo build uses: actions-rs/cargo@v1 with: command: build args: --release #\ninstall the latest stable node version at the time of writing - name: Node v16\nuses: actions/setup-node@v2 with: node-version: 16.x # install our Node.js\ndependencies with Yarn - name: Yarn install run: yarn install working-directory:\nwebdriver/webdriverio # install the latest version of `tauri-driver`. # note:\nthe tauri-driver version is independent of any other Tauri versions - name:\nInstall tauri-driver uses: actions-rs/cargo@v1 with: command: install args:\ntauri-driver # run the WebdriverIO test suite. # we run it through `xvfb-run`\n(the dependency we installed earlier) to have a fake # display server which\nallows our application to run headless without any changes to the code - name:\nWebdriverIO run: xvfb-run yarn test working-directory: webdriver/webdriverio ```\n[WebDriver]: https://www.w3.org/TR/webdriver/ [`tauri-driver`]:\nhttps://crates.io/crates/tauri-driver [WebdriverIO]: https://webdriver.io/\n[previously built together]: example/webdriverio","url":"https://tauri.studio/docs/testing/webdriver/ci"},{"id":"prose_docs_testing_webdriver_introduction_md","title":"Introduction","area":"testing","section":"webdriver","headings":["System Dependencies","Example Application"],"subHeadings":["Linux","Windows"],"code":["sh"],"text":"import Alert from '@theme/Alert' Webdriver support for Tauri is still in\npre-alpha. Tooling that is dedicated to it such as [tauri-driver] is still in\nactive development and may change as necessary over time. Additionally, only\nWindows and Linux are currently supported. [WebDriver] is a standardized\ninterface to interact with web documents that is primarily intended for\nautomated testing. Tauri supports the [WebDriver] interface by leveraging the\nnative platform's [WebDriver] server underneath a cross-platform wrapper\n[`tauri-driver`]. ## System Dependencies Install the latest [`tauri-driver`] or\nupdate an existing installation by running: ```sh cargo install tauri-driver ```\nBecause we currently utilize the platform's native [WebDriver] server, there are\nsome requirements for running [`tauri-driver`] on supported platforms. Platform\nsupport is currently limited to Linux and Windows. ### Linux We use\n`WebKitWebDriver` on linux platforms. Check if this binary exists already\n(command `which WebKitWebDriver`) as some distributions bundle it with the\nregular webkit package. Other platforms may have a separate package for them\nsuch as `webkit2gtk-driver` on Debian based distributions. ### Windows Make sure\nto grab the version of [Microsoft Edge Driver] that matches your Windows' Edge\nversion that the application is being built and tested on. On up-to-date Window\ninstalls, this should almost always be the latest stable version. If the two\nversions do not match, you may experience your WebDriver testing suite hanging\nwhile trying to connect. The download contains a binary called\n`msedgedriver.exe`. [`tauri-driver`] looks for that binary in the `$PATH` so\nmake sure it's either available on the path or use the `--native-driver` option\non [`tauri-driver`]. On Windows CI machines, you may want to download this\nautomatically as part of the CI setup process to ensure the Edge and Edge Driver\nversions stay in sync. A guide on how to do this may be added at a later date.\n## Example Application The [next section](example/setup) of the guide will show\nstep-by-step how to create a minimal example application that is tested with\nWebDriver. If you prefer to just see the result of the guide and look over a\nfinished minimal codebase that utilizes it then you can look at\nhttps://github.com/chippers/hello_tauri. That example also comes with a CI\nscript to test with GitHub actions, but you may still be interested in the\n[WebDriver CI](ci) guide as it explains the concept a bit more. [WebDriver]:\nhttps://www.w3.org/TR/webdriver/ [`tauri-driver`]:\nhttps://crates.io/crates/tauri-driver [tauri-driver]:\nhttps://crates.io/crates/tauri-driver [Microsoft Edge Driver]:\nhttps://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/","url":"https://tauri.studio/docs/testing/webdriver/introduction"},{"id":"prose_docs_testing_webdriver_example_selenium_md","title":"Selenium","area":"testing","parentSection":"webdriver","section":"example","headings":["Create a Directory for the Tests","Initializing a Selenium Project","Testing","Running the Test Suite"],"subHeadings":[],"code":["sh",null,"text"],"text":"import Alert from '@theme/Alert' import Tabs from '@theme/Tabs' import TabItem\nfrom '@theme/TabItem' This [Selenium] guide expects you to have already gone\nthrough the [example Application setup] in order to follow step-by-step. The\ngeneral information may still be useful otherwise. This WebDriver testing\nexample will use [Selenium] and a popular Node.js testing suite. It is expected\nto already have Node.js installed, along with `npm` or `yarn` although the\n[finished example project] uses `yarn`. ## Create a Directory for the Tests\nLet's start off by creating a space in our project to write these tests. We are\ngoing to be using a nested directory for this example project as we will later\nalso go over other frameworks, but typically you will only need to use one.\nCreate the directory we will use with `mkdir -p webdriver/selenium`. The rest of\nthis guide will assume you are inside the `webdriver/selenium` directory. ##\nInitializing a Selenium Project We will be using a pre-existing `package.json`\nto bootstrap this test suite because we have already chosen specific\ndependencies to use and want to showcase a simple working solution. The bottom\nof this section has a collapsed guide on how to set it up from scratch.\n`package.json`: ```json { \"name\": \"selenium\", \"version\": \"1.0.0\", \"private\":\ntrue, \"scripts\": { \"test\": \"mocha\" }, \"dependencies\": { \"chai\": \"^4.3.4\",\n\"mocha\": \"^9.0.3\", \"selenium-webdriver\": \"^4.0.0-beta.4\" } } ``` We have a\nscript which runs [Mocha] as a test framework exposed as the `test` command. We\nalso have various dependencies that we will be using to run the tests. [Mocha]\nas the testing framework, [Chai] as the assertion library, and\n[`selenium-webdriver`] which is the Node.js [Selenium] package. Click me if you\nwant to see how to set a project up from scratch If you wanted to install the\ndependencies from scratch, just run the following command. ```sh npm install\nmocha chai selenium-webdriver ``` ```sh yarn add mocha chai selenium-webdriver\n``` I suggest also adding a `\"test\": \"mocha\"` item in the `package.json`\n`\"scripts\"` key so that running mocha can be called simply with ```sh npm test\n``` ```sh yarn test ``` ## Testing Unlike the [WebdriverIO Test\nSuite](webdriverio#config), Selenium does not come out of the box with a Test\nSuite and leaves it up to the developer to build those out. We chose [Mocha]\nwhich is pretty neutral, and not related to WebDrivers at all, so our script\nwill need to do a bit of work to set up everything for us in the right order.\n[Mocha] expects a testing file at `test/test.js` by default, so let's create\nthat file now. `test/test.js`: ```js const os = require(\"os\"); const path =\nrequire(\"path\"); const { expect } = require(\"chai\"); const { spawn, spawnSync }\n= require(\"child_process\"); const { Builder, By, Capabilities } =\nrequire(\"selenium-webdriver\"); // create the path to the expected application\nbinary const application = path.resolve( __dirname, \"..\", \"..\", \"..\", \"target\",\n\"release\", \"hello-tauri-webdriver\" ); // keep track of the webdriver instance we\ncreate let driver; // keep track of the tauri-driver process we start let\ntauriDriver; before(async function() { // set timeout to 2 minutes to allow the\nprogram to build if it needs to this.timeout(120000) // ensure the program has\nbeen built spawnSync(\"cargo\", [\"build\", \"--release\"]); // start tauri-driver\ntauriDriver = spawn( path.resolve(os.homedir(), \".cargo\", \"bin\",\n\"tauri-driver\"), [], { stdio: [null, process.stdout, process.stderr] } ); const\ncapabilities = new Capabilities(); capabilities.set(\"tauri:options\", {\napplication }); capabilities.setBrowserName(\"wry\"); // start the webdriver\nclient driver = await new Builder() .withCapabilities(capabilities)\n.usingServer(\"http://localhost:4444/\") .build(); }); after(async function() { //\nstop the webdriver session await driver.quit(); // kill the tauri-driver process\ntauriDriver.kill(); }); describe(\"Hello Tauri\", () => { it(\"should be cordial\",\nasync () => { const text = await driver.findElement(By.css(\"body >\nh1\")).getText(); expect(text).to.match(/^[hH]ello/); }); it(\"should be excited\",\nasync () => { const text = await driver.findElement(By.css(\"body >\nh1\")).getText(); expect(text).to.match(/!$/); }); it(\"should be easy on the\neyes\", async () => { // selenium returns color css values as rgb(r, g, b) const\ntext = await driver.findElement(By.css(\"body\")).getCssValue(\"background-color\");\nconst rgb = text.match(/^rgb\\((?\\d+), (?\\d+), (?\\d+)\\)$/).groups;\nexpect(rgb).to.have.all.keys('r','g','b'); const luma = 0.2126 * rgb.r + 0.7152\n* rgb.g + 0.0722 * rgb.b ; expect(luma).to.be.lessThan(100) }); }); ``` If you\nare familiar with JS testing frameworks, `describe`, `it`, and `expect` should\nlook familiar. We also have semi-complex `before()` and `after()` callbacks to\nsetup and teardown mocha. Lines that are not the tests themselves have comments\nexplaining what the setup and teardown code is doing. If you were familiar with\nthe Spec file from the [WebdriverIO example](webdriverio#spec), you will notice\na lot more code that isn't tests, as we have to set up a few more WebDriver\nrelated items. ## Running the Test Suite Now that we are all set up with our\ndependencies and our test script, lets run it! ```sh npm test ``` ```sh yarn\ntest ``` We should see output the following output: ```text ➜ selenium\ngit:(main) ✗ yarn test yarn run v1.22.11 $ mocha Hello Tauri ✔ should be cordial\n(120ms) ✔ should be excited ✔ should be easy on the eyes 3 passing (588ms) Done\nin 0.93s. ``` We can see that our `Hello Tauri` sweet we created with `decribe`\nhad all 3 items we created with `it` pass their tests! With [Selenium] and some\nhooking up to a test suite, we just enabled e2e testing without modifying our\nTauri application at all! [Selenium]: https://selenium.dev/ [finished example\nproject]: https://github.com/chippers/hello_tauri [example Application setup]:\nsetup [Mocha]: https://mochajs.org/ [Chai]: https://www.chaijs.com/\n[`selenium-webdriver`]: https://www.npmjs.com/package/selenium-webdriver","url":"https://tauri.studio/docs/testing/webdriver/example/selenium"},{"id":"prose_docs_testing_webdriver_example_setup_md","title":"Setup Example","area":"testing","parentSection":"webdriver","section":"example","headings":["Initializing a Cargo Project","Creating a Minimal Frontend","Adding Tauri to the Cargo Project","Tauri Configuration","Running the Example Application"],"subHeadings":[],"code":["html","toml","rust","json"],"text":"HELLO, TAURI!","url":"https://tauri.studio/docs/testing/webdriver/example/setup"},{"id":"prose_docs_testing_webdriver_example_webdriverio_md","title":"WebdriverIO","area":"testing","parentSection":"webdriver","section":"example","headings":["Create a Directory for the Tests","Initializing a WebdriverIO Project","Config","Spec","Running the Test Suite"],"subHeadings":[],"code":["sh","text"],"text":"import Alert from '@theme/Alert' import Tabs from '@theme/Tabs' import TabItem\nfrom '@theme/TabItem' This [WebdriverIO] guide expects you to have already gone\nthrough the [example Application setup] in order to follow step-by-step. The\ngeneral information may still be useful otherwise. This WebDriver testing\nexample will use [WebdriverIO] and its testing suite. It is expected to already\nhave Node.js installed, along with `npm` or `yarn` although the [finished\nexample project] uses `yarn`. ## Create a Directory for the Tests Let's start\noff by creating a space in our project to write these tests. We are going to be\nusing a nested directory for this example project as we will later also go over\nother frameworks, but typically you will only need to use one. Create the\ndirectory we will use with `mkdir -p webdriver/webdriverio`. The rest of this\nguide will assume you are inside the `webdriver/webdriverio` directory. ##\nInitializing a WebdriverIO Project We will be using a pre-existing\n`package.json` to bootstrap this test suite because we have already chosen\nspecific [WebdriverIO] config options and want to showcase a simple working\nsolution. The bottom of this section has a collapsed guide on how to set it up\nfrom scratch. `package.json`: ```json { \"name\": \"webdriverio\", \"version\":\n\"1.0.0\", \"private\": true, \"scripts\": { \"test\": \"wdio run wdio.conf.js\" },\n\"dependencies\": { \"@wdio/cli\": \"^7.9.1\" }, \"devDependencies\": {\n\"@wdio/local-runner\": \"^7.9.1\", \"@wdio/mocha-framework\": \"^7.9.1\",\n\"@wdio/spec-reporter\": \"^7.9.0\" } } ``` We have a script which runs a\n[WebdriverIO] config as a test suite exposed as the `test` command. We also have\nvarious dependencies that were added by the `@wdio/cli` command when we first\nset it up. In short, these dependencies are for the most simple setup using a\nlocal WebDriver runner, [Mocha] as the test framework, and a simple Spec\nReporter. Click me if you want to see how to set a project up from scratch The\nCLI is interactive, and you may choose the tools to work with yourself. Note\nthat you will likely diverge from the rest of the guide, and need to set up the\ndifferences yourself. Let's add the [WebdriverIO] CLI to this npm project. ```sh\nnpm install @wdio/cli ``` ```sh yarn add @wdio/cli ``` To then run the\ninteractive config command to set up a [WebdriverIO] test suite, you can then\nrun: ```sh npx wdio config ``` ```sh yarn wdio config ``` ## Config You may have\nnoticed that the `test` script in our `package.json` mentions a file\n`wdio.conf.js`. That's the [WebdriverIO] config file which controls most aspects\nof our testing suite. `wdio.conf.js`: ```js const os = require(\"os\"); const path\n= require(\"path\"); const { spawn, spawnSync } = require(\"child_process\"); //\nkeep track of the `tauri-driver` child process let tauriDriver; exports.config =\n{ specs: [\"./test/specs/**/*.js\"], maxInstances: 1, capabilities: [ {\nmaxInstances: 1, \"tauri:options\": { application:\n\"../../target/release/hello-tauri-webdriver\", }, }, ], reporters: [\"spec\"],\nframework: \"mocha\", mochaOpts: { ui: \"bdd\", timeout: 60000, }, // ensure the\nrust project is built since we expect this binary to exist for the webdriver\nsessions onPrepare: () => spawnSync(\"cargo\", [\"build\", \"--release\"]), // ensure\nwe are running `tauri-driver` before the session starts so that we can proxy the\nwebdriver requests beforeSession: () => (tauriDriver = spawn(\npath.resolve(os.homedir(), \".cargo\", \"bin\", \"tauri-driver\"), [], { stdio: [null,\nprocess.stdout, process.stderr] } )), // clean up the `tauri-driver` process we\nspawned at the start of the session afterSession: () => tauriDriver.kill(), };\n``` If you are interested in the properties on `exports.config` object, then I\n[suggest reading the documentation] for it. For non-WDIO specific items, there\nare comments explaining why we are running commands in `onPrepare`,\n`beforeSession`, and `afterSession`. We also have our specs set to\n`\"./test/specs/**/*.js\"`, so let's create a spec now. ## Spec A spec contains\nthe code that is testing your actual application. The test runner will load\nthese specs and automatically run them as it sees fit. Let's create our spec now\nin the directory we specified. `test/specs/example.e2e.js`: ```js // calculates\nthe luma from a hex color `#abcdef` function luma(hex) { if\n(hex.startsWith(\"#\")) { hex = hex.substring(1); } const rgb = parseInt(hex, 16);\nconst r = (rgb >> 16) & 0xff; const g = (rgb >> 8) & 0xff; const b = (rgb >> 0)\n& 0xff; return 0.2126 * r + 0.7152 * g + 0.0722 * b; } describe(\"Hello Tauri\",\n() => { it(\"should be cordial\", async () => { const header = await $(\"body >\nh1\"); const text = await header.getText(); expect(text).toMatch(/^[hH]ello/);\n}); it(\"should be excited\", async () => { const header = await $(\"body > h1\");\nconst text = await header.getText(); expect(text).toMatch(/!$/); }); it(\"should\nbe easy on the eyes\", async () => { const body = await $(\"body\"); const\nbackgroundColor = await body.getCSSProperty(\"background-color\");\nexpect(luma(backgroundColor.parsed.hex)).toBeLessThan(100); }); }); ``` The\n`luma` function on top is just a helper function for one of our tests and is not\nrelated to the actual testing of the application. If you are familiar with other\ntesting frameworks, you may notice similar functions being exposed that are used\nsuch as `describe`, `it`, and `expect`. The other APIs, such as items like `$`\nand the methods it exposes is covered by the [WebdriverIO API\ndocs](https://webdriver.io/docs/api). ## Running the Test Suite Now that we are\nall set up with a config and a spec, let's run it! ```sh npm test ``` ```sh yarn\ntest ``` We should see output the following output: ```text ➜ webdriverio\ngit:(main) ✗ yarn test yarn run v1.22.11 $ wdio run wdio.conf.js Execution of 1\nworkers started at 2021-08-17T08:06:10.279Z [0-0] RUNNING in undefined -\n/test/specs/example.e2e.js [0-0] PASSED in undefined -\n/test/specs/example.e2e.js \"spec\" Reporter:\n------------------------------------------------------------------ [wry 0.12.1\nlinux #0-0] Running: wry (v0.12.1) on linux [wry 0.12.1 linux #0-0] Session ID:\n81e0107b-4d38-4eed-9b10-ee80ca47bb83 [wry 0.12.1 linux #0-0] [wry 0.12.1 linux\n#0-0] » /test/specs/example.e2e.js [wry 0.12.1 linux #0-0] Hello Tauri [wry\n0.12.1 linux #0-0] ✓ should be cordial [wry 0.12.1 linux #0-0] ✓ should be\nexcited [wry 0.12.1 linux #0-0] ✓ should be easy on the eyes [wry 0.12.1 linux\n#0-0] [wry 0.12.1 linux #0-0] 3 passing (244ms) Spec Files: 1 passed, 1 total\n(100% completed) in 00:00:01 Done in 1.98s. ``` We see the Spec Reporter tell us\nthat all 3 tests from the `test/specs/example.e2e.js` file, along with the final\nreport `Spec Files: 1 passed, 1 total (100% completed) in 00:00:01`. Using the\n[WebdriverIO] test suite, we just easily enabled e2e testing for our Tauri\napplication from just a few lines of configuration and a single command to run\nit! Even better, we didn't have to modify the application at all. [WebdriverIO]:\nhttps://webdriver.io/ [finished example project]:\nhttps://github.com/chippers/hello_tauri [example Application setup]: setup\n[Mocha]: https://mochajs.org/ [suggest reading the documentation]:\nhttps://webdriver.io/docs/configurationfile","url":"https://tauri.studio/docs/testing/webdriver/example/webdriverio"}] \ No newline at end of file diff --git a/packages/tauri-search/src/generated/repos/documents.json b/packages/tauri-search/src/generated/repos/documents.json index 5d4a585..ae7e4ff 100644 --- a/packages/tauri-search/src/generated/repos/documents.json +++ b/packages/tauri-search/src/generated/repos/documents.json @@ -1 +1 @@ -[{"id":"github_tauri_apps_tauri","name":"tauri","description":"Build smaller, faster, and more secure desktop applications with a web frontend.","kind":"code","stars":30895,"watchers":30895,"subscribers":311,"openIssues":130,"forks":769,"defaultBranch":"dev","language":"Rust","topics":["hacktoberfest","high-performance","rust","webview","works-with-clojurescript","works-with-construct","works-with-elm","works-with-flutter","works-with-gatsby","works-with-mint","works-with-phaser","works-with-quasar","works-with-react","works-with-reason","works-with-svelte","works-with-vue","works-with-yew"],"isTemplate":false,"lastUpdated":"2022-02-12T02:51:37Z","createdAt":"2019-07-13T09:09:37Z","license":"Other","text":"\"Tauri\"\n\n[![status](https://img.shields.io/badge/Status-Beta-green.svg)](https://github.com/tauri-apps/tauri/tree/dev)\n[![License](https://img.shields.io/badge/License-MIT%20or%20Apache%202-green.svg)](https://opencollective.com/tauri)\n[![test library](https://img.shields.io/github/workflow/status/tauri-apps/tauri/test%20library?label=test%20library)](https://github.com/tauri-apps/tauri/actions?query=workflow%3A%22test+library%22)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)\n\n[![Chat Server](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/SpmNs4S)\n[![devto](https://img.shields.io/badge/blog-dev.to-black.svg)](https://dev.to/tauri)\n[![devto](https://img.shields.io/badge/documentation-tauri.studio-purple.svg)](https://tauri.studio/docs/get-started/intro)\n[![https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg](https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg)](https://good-labs.github.io/greater-good-affirmation)\n[![support](https://img.shields.io/badge/sponsor-open%20collective-blue.svg)](https://opencollective.com/tauri)\n\n## Current Releases\n\n| Component | Description | Version | Lin | Win | Mac |\n| --------------------------------------------------------------------------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | --- | --- | --- |\n| [**cli.rs**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) | create, develop and build apps | [![](https://img.shields.io/crates/v/tauri-cli.svg)](https://crates.io/crates/tauri-cli) | ✅ | ✅ | ✅ |\n| [**cli.js**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli/node) | Node.js CLI wrapper for cli.rs | [![](https://img.shields.io/npm/v/@tauri-apps/cli.svg)](https://www.npmjs.com/package/@tauri-apps/cli) | ✅ | ✅ | ✅ |\n| [**api.js**](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) | JS API for interaction with Rust backend | [![](https://img.shields.io/npm/v/@tauri-apps/api.svg)](https://www.npmjs.com/package/@tauri-apps/api) | ✅ | ✅ | ✅ |\n| [**create-tauri-app**](https://github.com/tauri-apps/tauri/tree/dev/tooling/create-tauri-app) | Get started with your first Tauri app | [![](https://img.shields.io/npm/v/create-tauri-app.svg)](https://www.npmjs.com/package/create-tauri-app) | ✅ | ✅ | ✅ |\n| [**vue-cli-plugin-tauri**](https://github.com/tauri-apps/vue-cli-plugin-tauri/) | Vue CLI plugin for Tauri | [![](https://img.shields.io/npm/v/vue-cli-plugin-tauri.svg)](https://www.npmjs.com/package/vue-cli-plugin-tauri) | ✅ | ✅ | ✅ |\n| [**core**](https://github.com/tauri-apps/tauri/tree/dev/core/tauri) | runtime core | [![](https://img.shields.io/crates/v/tauri.svg)](https://crates.io/crates/tauri) | ✅ | ✅ | ✅ |\n| [**bundler**](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler) | manufacture the final binaries | [![](https://img.shields.io/crates/v/tauri-bundler.svg)](https://crates.io/crates/tauri-bundler) | ✅ | ✅ | ✅ |\n\n## Introduction\nTauri is a framework for building tiny, blazing fast binaries for all major desktop platforms. Developers can integrate any front-end framework that compiles to HTML, JS and CSS for building their user interface. The backend of the application is a rust-sourced binary with an API that the front-end can interact with.\n\nThe user interface in Tauri apps currently leverages [`tao`](https://docs.rs/tao) as a window handling library on macOS and Windows, and [`gtk`](https://gtk-rs.org/docs/gtk/) on Linux via the **Tauri-team** incubated and maintained [WRY](https://github.com/tauri-apps/wry), which creates a unified interface to the system webview (and other goodies like Menu and Taskbar), leveraging WebKit on macOS, WebView2 on Windows and WebKitGTK on Linux.\n\nTo learn more about the details of how all of these pieces fit together, please consult this [ARCHITECTURE.md](https://github.com/tauri-apps/tauri/blob/dev/ARCHITECTURE.md) document.\n\n## Get Started\nIf you are interested in making a tauri-app, please visit the [documentation website](https://tauri.studio). This README is directed towards those who are interested in contributing to the core library. But if you just want a quick overview about where `tauri` is at in its development, here's a quick burndown:\n\n### Platforms\n- [x] Windows 7,8,10\n- [x] Linux\n- [x] macOS\n- [ ] iOS (in progress)\n- [ ] android (soon)\n\n### App Bundles\n- [x] App Icons\n- [x] Build on MacOS (.app, .dmg)\n- [x] Build on Linux (.deb, AppImage)\n- [x] Build on Windows (.exe, .msi)\n- [x] Copy Buffer\n- [x] Device Notifications (toast)\n- [x] Self Updater\n- [x] App Signing\n- [x] Frameless Mode\n- [x] Transparent Mode\n- [x] Multiwindow Mode\n- [x] Tray\n- [ ] deeplink RPC (in progress)\n- [ ] One-Time commands (coming soon)\n\n### Security Features\n- [x] localhost-free (:fire:)\n- [x] custom protocol for secure mode\n- [x] Dynamic ahead of Time Compilation (dAoT) with functional tree-shaking\n- [x] functional Address Space Layout Randomization\n- [x] OTP salting of function names and messages at runtime\n- [x] CSP Injection\n\n### Utilities\n- [x] GH Action for creating binaries for all platforms\n- [x] VS Code Extension\n- [x] Tauri Core Plugins\n- [x] Update core dependencies automatically from the command line\n- [x] Rust-based CLI\n\n### Comparison between Tauri and Electron\n\n| Detail | Tauri | Electron |\n| -------------------------- | ------ | -------------------- |\n| Installer Size Linux | 3.1 MB | 52.1 MB |\n| Memory Consumption Linux | 180 MB | 462 MB |\n| Launch Time Linux | 0.39s | 0.80s |\n| Interface Service Provider | WRY | Chromium |\n| Backend Binding | Rust | Node.js (ECMAScript) |\n| Underlying Engine | Rust | V8 (C/C++) |\n| FLOSS | Yes | No |\n| Multithreading | Yes | Yes |\n| Bytecode Delivery | Yes | No |\n| Multiple Windows | Yes | Yes |\n| Auto Updater | Yes | Yes1 |\n| Custom App Icon | Yes | Yes |\n| Windows Binary | Yes | Yes |\n| MacOS Binary | Yes | Yes |\n| Linux Binary | Yes | Yes |\n| iOS Binary | Soon | No |\n| Android Binary | Soon | No |\n| Desktop Tray | Yes | Yes |\n| Sidecar Binaries | Yes | No |\n\n#### Notes\n1. Electron has no native auto updater on Linux, but is offered by electron-packager\n\n## Development\n\nTauri is a system composed of a number of moving pieces:\n\n### Infrastructure\n- Git for code management\n- GitHub for project management\n- GitHub actions for CI and CD\n- Discord for discussions\n- Netlify-hosted documentation website\n- DigitalOcean meilisearch instance\n\n### Major Runtimes\n- Node.js for running the CLI (deno and pure rust are on the roadmap)\n- Cargo for testing, running the dev service, building binaries and as the runtime harness for the webview\n\n### Major Languages\n- Rust for the CLI\n- EcmaScript bindings to the Rust API, written in typescript\n- Rust for bindings, rust side of the API, harnesses\n- Rust plugins to Tauri backend\n\n### Operating systems\nTauri core can be developed on Mac, Linux and Windows, but you are encouraged to use the latest possible operating systems and build tools for your OS.\n\n### Contributing\nBefore you start working on something, it's best to check if there is an existing issue first. It's also is a good idea to stop by the Discord server and confirm with the team if it makes sense or if someone is already working on it.\n\nPlease make sure to read the [Contributing Guide](./.github/CONTRIBUTING.md) before making a pull request.\n\nThank you to everyone contributing to Tauri!\n\n### Documentation\nDocumentation in a polyglot system is a tricky proposition. To this end, we prefer to use inline documentation of Rust code and at JSDoc in typescript / javascript code. We autocollect these and publish them using Docusaurus v2 and netlify. Here is the hosting repository for the documentation site: https://github.com/tauri-apps/tauri-docs\n\n### Testing & Linting\nTest all the things! We have a number of test suites, but are always looking to improve our coverage:\n- Rust (`cargo test`) => sourced via inline `#[cfg(test)]` declarations\n- TS (`jest`) => via spec files\n- Smoke Tests (run on merges to latest)\n- eslint, clippy\n\n### CI/CD\nWe recommend you read this article to understand better how we run our pipelines: https://www.jacobbolda.com/setting-up-ci-and-cd-for-tauri/\n\n## Organization\nTauri aims to be a sustainable collective based on principles that guide [sustainable free and open software communities](https://sfosc.org). To this end it has become a Programme within the [Commons Conservancy](https://commonsconservancy.org/), and you can contribute financially via [Open Collective](https://opencollective.com/tauri).\n\n## Semver\n**tauri** is following [Semantic Versioning 2.0](https://semver.org/).\n\n## Licenses\nCode: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy.\n\nMIT or MIT/Apache 2.0 where applicable.\n\nLogo: CC-BY-NC-ND\n- Original Tauri Logo Designs by [Alve Larsson](https://alve.io/), [Daniel Thompson-Yvetot](https://github.com/nothingismagick) and [Guillaume Chau](https://github.com/akryum)\n\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_large)\n","url":"https://github.com/tauri-apps/tauri"},{"id":"github_tauri_apps_wry","name":"wry","description":"Cross-platform WebView library in Rust for Tauri.","kind":"code","stars":943,"watchers":943,"subscribers":25,"openIssues":41,"forks":62,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-11T12:35:40Z","createdAt":"2020-07-12T15:12:44Z","license":"Other","text":"\"WRY\n\n[![](https://img.shields.io/crates/v/wry?style=flat-square)](https://crates.io/crates/wry) [![](https://img.shields.io/docsrs/wry?style=flat-square)](https://docs.rs/wry/) ![](https://img.shields.io/crates/l/wry?style=flat-square)\n\nCross-platform WebView rendering library in Rust that supports all major desktop platforms like Windows, macOS, and Linux.\n\n
\n \n \n \n
\n\n## Overview\n\nWry connects the web engine on each platform and provides easy to use and unified interface to render WebView. It also re-exports [tao] as a module for event loop and window creation.\n\n[tao]: https://crates.io/crates/tao\n\n## Usage\n\nThe minimum example to create a Window and browse a website looks like following:\n\n```rust\nfn main() -> wry::Result<()> {\n use wry::{\n application::{\n event::{Event, StartCause, WindowEvent},\n event_loop::{ControlFlow, EventLoop},\n window::WindowBuilder,\n },\n webview::WebViewBuilder,\n };\n\n let event_loop = EventLoop::new();\n let window = WindowBuilder::new()\n .with_title(\"Hello World\")\n .build(&event_loop)?;\n let _webview = WebViewBuilder::new(window)?\n .with_url(\"https://tauri.studio\")?\n .build()?;\n\n event_loop.run(move |event, _, control_flow| {\n *control_flow = ControlFlow::Wait;\n\n match event {\n Event::NewEvents(StartCause::Init) => println!(\"Wry has started!\"),\n Event::WindowEvent {\n event: WindowEvent::CloseRequested,\n ..\n } => *control_flow = ControlFlow::Exit,\n _ => (),\n }\n });\n}\n```\n\nThere are also more samples under `examples`, you can enter commands like following to try them:\n\n```\ncargo run --example multi_window\n```\n\nFor more information, please read the documentation below.\n\n## [Documentation](https://docs.rs/wry)\n\n## Platform-specific notes\n\nAll platforms uses [tao](https://github.com/tauri-apps/tao) to build the window, and wry re-export it as application module. Here are the underlying web engine each platform uses, and some dependencies you might need to install.\n\n### Linux\n\nTao uses [gtk-rs](https://gtk-rs.org/) and its related libraries for window creation and wry also needs [WebKitGTK](https://webkitgtk.org/) for WebView. So please make sure following packages are installed:\n\n#### Arch Linux / Manjaro:\n\n```bash\nsudo pacman -S webkit2gtk libappindicator-gtk3\n```\n\n#### Debian / Ubuntu:\n\n```bash\nsudo apt install libwebkit2gtk-4.0-dev libappindicator3-dev\n```\n\n#### Fedora\n\n```bash\nsudo dnf install gtk3-devel webkit2gtk3-devel libappindicator-gtk3-devel\n```\n\n### macOS\n\nWebKit is native on macOS so everything should be fine.\n\nIf you are cross-compiling for macOS using [osxcross](https://github.com/tpoechtrager/osxcross) and encounter a runtime panic like `Class with name WKWebViewConfiguration could not be found` it's possible that `WebKit.framework` has not been linked correctly, to fix this set the `RUSTFLAGS` environment variable:\n\n```\nRUSTFLAGS=\"-l framework=WebKit\" cargo build --target=x86_64-apple-darwin --release\n```\n\n### Windows\n\nWebView2 provided by Microsoft Edge Chromium is used. So wry supports Windows 7, 8, and 10.\n\n## License\nApache-2.0/MIT\n","url":"https://github.com/tauri-apps/wry"},{"id":"github_tauri_apps_tao","name":"tao","description":"The TAO of cross-platform windowing. A library in Rust built for Tauri.","kind":"code","stars":200,"watchers":200,"subscribers":13,"openIssues":51,"forks":21,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-10T17:14:21Z","createdAt":"2021-05-03T02:40:47Z","license":"Apache License 2.0","text":"\"TAO\n\n[![](https://img.shields.io/crates/v/tao?style=flat-square)](https://crates.io/crates/tao) [![](https://img.shields.io/docsrs/tao?style=flat-square)](https://docs.rs/tao/) ![](https://img.shields.io/crates/l/tao?style=flat-square)\n\n[![Chat Server](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/SpmNs4S)\n[![devto](https://img.shields.io/badge/blog-dev.to-black.svg)](https://dev.to/tauri)\n[![devto](https://img.shields.io/badge/documentation-tauri.studio-purple.svg)](https://tauri.studio/docs/getting-started/intro)\n[![https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg](https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg)](https://good-labs.github.io/greater-good-affirmation)\n[![support](https://img.shields.io/badge/sponsor-open%20collective-blue.svg)](https://opencollective.com/tauri)\n\n\nCross-platform application window creation library in Rust that supports all major platforms like \nWindows, macOS, Linux, iOS and Android. Built for you, maintained for Tauri.\n\n### Cargo Features\n\nTao provides the following features, which can be enabled in your `Cargo.toml` file:\n* `serde`: Enables serialization/deserialization of certain types with [Serde](https://crates.io/crates/serde).\n* `tray`: Enables system tray and more menu item variants on **Linux**. This flag is enabled by default.\n You can still create those types if you disable it. They just don't create the actual objects. We set this flag because some implementations require more installed packages. Disable this if you don't want to install `libappindicator` package.\n* `ayatana`: Enable this if you wish to use more update `libayatana-appindicator` since `libappindicator` is no longer\n maintained.\n\n## Platform-specific notes\n\n### Android\n\nThis library makes use of the [ndk-rs](https://github.com/rust-windowing/android-ndk-rs) crates, refer to that repo for more documentation.\n\nRunning on an Android device needs a dynamic system library, add this to Cargo.toml:\n```toml\n[[example]]\nname = \"request_redraw_threaded\"\ncrate-type = [\"cdylib\"]\n```\n\nAnd add this to the example file to add the native activity glue:\n\n```rust\n#[cfg_attr(target_os = \"android\", ndk_glue::main(backtrace = \"on\"))]\nfn main() {\n ...\n}\n```\n\nAnd run the application with `cargo apk run --example request_redraw_threaded`\n\n### Linux\n\nGtk and its related libraries are used to build the support of Linux. Be sure to install following packages before building:\n\n#### Arch Linux / Manjaro:\n\n```bash\nsudo pacman -S gtk3 libappindicator-gtk3\n```\n\n#### Debian / Ubuntu:\n\n```bash\nsudo apt install libgtk-3-dev libappindicator3-dev\n```\n\n#### MacOS\n\nTo ensure compatibility with older MacOS systems, tao links to\nCGDisplayCreateUUIDFromDisplayID through the CoreGraphics framework.\nHowever, under certain setups this function is only available to be linked\nthrough the newer ColorSync framework. So, tao provides the\n`TAO_LINK_COLORSYNC` environment variable which can be set to `1` or `true`\nwhile compiling to enable linking via ColorSync.\n\n### Acknowledgement\n\nWe would like to thank the authors and contributors to [winit](https://crates.io/crates/winit)\nfor their groundbreaking work upon which this crate is not only based, but\nalso leans heavily upon. Thankyou!!!\n","url":"https://github.com/tauri-apps/tao"},{"id":"github_tauri_apps_tauri_action","name":"tauri-action","description":"Build your Web application as a Tauri binary for MacOS, Linux and Windows","kind":"unknown","stars":102,"watchers":102,"subscribers":10,"openIssues":20,"forks":23,"defaultBranch":"dev","language":"TypeScript","topics":["github-actions","hacktoberfest"],"isTemplate":false,"lastUpdated":"2022-02-01T20:21:04Z","createdAt":"2020-07-07T21:41:23Z","license":"MIT License","text":"# Tauri GitHub Action\n\nThis GitHub Action builds your Web application as a Tauri native binary for MacOS, Linux and Windows.\nIf your project doesn't include the Tauri files, we create it at compile time, so if you don't need to use Tauri's API, you can just ship native apps through this Action.\n\n# Usage\n\nThis GitHub Action has three main usages: test the build pipeline of your Tauri app, uploading Tauri artifacts to an existing release, and creating a new release with the Tauri artifacts.\n\n## Testing the Build\n\n```yml\nname: \"test-on-pr\"\non: [pull_request]\n\njobs:\n test-tauri:\n strategy:\n fail-fast: false\n matrix:\n platform: [macos-latest, ubuntu-latest, windows-latest]\n\n runs-on: ${{ matrix.platform }}\n steps:\n - uses: actions/checkout@v2\n - name: setup node\n uses: actions/setup-node@v1\n with:\n node-version: 12\n - name: install Rust stable\n uses: actions-rs/toolchain@v1\n with:\n toolchain: stable\n - name: install webkit2gtk (ubuntu only)\n if: matrix.platform == 'ubuntu-latest'\n run: |\n sudo apt-get update\n sudo apt-get install -y webkit2gtk-4.0\n - name: install app dependencies and build it\n run: yarn && yarn build\n - uses: tauri-apps/tauri-action@v0\n env:\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\n## Creating a release and uploading the Tauri bundles\n\n```yml\nname: \"publish\"\non:\n push:\n branches:\n - release\n\njobs:\n publish-tauri:\n strategy:\n fail-fast: false\n matrix:\n platform: [macos-latest, ubuntu-latest, windows-latest]\n\n runs-on: ${{ matrix.platform }}\n steps:\n - uses: actions/checkout@v2\n - name: setup node\n uses: actions/setup-node@v1\n with:\n node-version: 12\n - name: install Rust stable\n uses: actions-rs/toolchain@v1\n with:\n toolchain: stable\n - name: install webkit2gtk (ubuntu only)\n if: matrix.platform == 'ubuntu-latest'\n run: |\n sudo apt-get update\n sudo apt-get install -y webkit2gtk-4.0\n - name: install app dependencies and build it\n run: yarn && yarn build\n - uses: tauri-apps/tauri-action@v0\n env:\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n with:\n tagName: app-v__VERSION__ # the action automatically replaces \\_\\_VERSION\\_\\_ with the app version\n releaseName: \"App v__VERSION__\"\n releaseBody: \"See the assets to download this version and install.\"\n releaseDraft: true\n prerelease: false\n```\n\n## Uploading the artifacts to a release\n\nNote that `actions/create-release` isn't maintained so you should find an alternative or let the Tauri Action handle the release.\n\n```yml\nname: \"test-on-pr\"\non: [pull_request]\n\njobs:\n create-release:\n runs-on: ubuntu-latest\n outputs:\n RELEASE_UPLOAD_ID: ${{ steps.create_release.outputs.id }}\n\n steps:\n - uses: actions/checkout@v2\n - name: setup node\n uses: actions/setup-node@v1\n with:\n node-version: 12\n - name: get version\n run: echo \"PACKAGE_VERSION=$(node -p \"require('./package.json').version\")\" >> $GITHUB_ENV\n - name: create release\n id: create_release\n uses: actions/create-release@v1.1.0\n env:\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n with:\n tag_name: app-v${{ env.PACKAGE_VERSION }}\n release_name: \"Desktop app v${{ env.PACKAGE_VERSION }}\"\n body: \"See the assets to download this version and install.\"\n draft: true\n prerelease: false\n build-tauri:\n needs: create-release\n strategy:\n fail-fast: false\n matrix:\n platform: [macos-latest, ubuntu-latest, windows-latest]\n\n runs-on: ${{ matrix.platform }}\n steps:\n - uses: actions/checkout@v2\n - name: setup node\n uses: actions/setup-node@v1\n with:\n node-version: 12\n - name: install Rust stable\n uses: actions-rs/toolchain@v1\n with:\n toolchain: stable\n - name: install webkit2gtk (ubuntu only)\n if: matrix.platform == 'ubuntu-latest'\n run: |\n sudo apt-get update\n sudo apt-get install -y webkit2gtk-4.0\n - name: install app dependencies and build it\n run: yarn && yarn build\n - uses: tauri-apps/tauri-action@v0\n env:\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n with:\n releaseId: ${{ needs.create-release.outputs.RELEASE_UPLOAD_ID }}\n```\n\n## Inputs\n\n| Name | Required | Description | Type | Default |\n| ------------------ | :------: | ------------------------------------------------------------------------------------------- | ------ | --------------------- |\n| `projectPath` | false | Path to the root of the project that will be built | string | . |\n| `configPath` | false | Path to the tauri.conf.json file if you want a configuration different from the default one | string | tauri.conf.json |\n| `distPath` | false | Path to the distributable folder with your index.html and JS/CSS | string | |\n| `releaseId` | false | The id of the release to upload artifacts as release assets | string | |\n| `tagName` | false | The tag name of the release to create | string | |\n| `releaseName` | false | The name of the release to create | string | |\n| `releaseBody` | false | The body of the release to create | string | |\n| `releaseDraft` | false | Whether the release to create is a draft or not | bool | false |\n| `prerelease` | false | Whether the release to create is a prerelease or not | bool | false |\n| `releaseCommitish` | false | Any branch or commit SHA the Git tag is created from, unused if the Git tag already exists | string | SHA of current commit |\n| `iconPath` | false | path to the PNG icon to use as app icon, relative to the projectPath | string | |\n| `includeDebug` | false | whether to include a debug build or not | bool | |\n| `tauriScript` | false | the script to execute the Tauri CLI | string | `yarn\\|npm tauri` |\n\n## Outputs\n\n| Name | Description |\n| ------------------ | ------------------------------------------------------------------ |\n| `releaseId` | The ID of the created release |\n| `releaseHtmlUrl` | The URL users can navigate to in order to view the created release |\n| `releaseUploadUrl` | The URL for uploading assets to the created release |\n\n# Caveats\n\n- You can use this Action on a repo that doesn't have Tauri configured. We automatically initialize Tauri before building, and configure it to use your Web artifacts.\n - You can configure Tauri with the `configPath`, `distPath` and `iconPath` options.\n- You can run custom Tauri CLI scripts with the `tauriScript` option. So instead of running `yarn tauri build` or `npx tauri build`, we'll execute `${tauriScript}`.\n - Useful when you need custom build functionality when creating Tauri apps e.g. a `desktop:build` script.\n- When your app isn't on the root of the repo, use the `projectPath` input.\n","url":"https://github.com/tauri-apps/tauri-action"},{"id":"github_tauri_apps_tauri_docs","name":"tauri-docs","description":"The source for all tauri project documentation.","kind":"documentation","stars":221,"watchers":221,"subscribers":17,"openIssues":55,"forks":86,"defaultBranch":"dev","language":"JavaScript","topics":["documentation","hacktoberfest","tauri"],"isTemplate":false,"lastUpdated":"2022-02-11T11:35:54Z","createdAt":"2020-03-09T00:22:43Z","license":"MIT License","text":"# Tauri Docs\n\nThis website is built using [Docusaurus 2](https://v2.docusaurus.io/) with [MeiliSearch](https://github.com/meilisearch/) for the docs indexation and is deployed by Netlify.\n\n[![Deploys By Netlify](https://www.netlify.com/img/global/badges/netlify-light.svg)](https://www.netlify.com)\n\nIf you seek to change something from **our guides**, please refer to [the docs folder](https://github.com/tauri-apps/tauri-docs/tree/dev/docs). \\\nWhen browsing the website, you will find edit links at the bottom of these docs.\n\nThe **API docs** are generated from our [Rust](https://github.com/tauri-apps/tauri/tree/dev/core/tauri) and [TypeScript](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) source code.\n\n## Installation\n\n```\n$ yarn\n```\n\n## Local Development\n\n```\n$ yarn start\n```\n\nThis command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server.\n\nTo develop in another language, use this command (setting your desired language):\n```\n$ yarn start --locale fr\n```\n\n## Build\n\n```\n$ yarn build\n```\n\nThis command generates static content and can be served using any static contents hosting service.\n\nTo build for only a specific language use:\n\n```\nyarn build --locale fr\n```\n\n## Deployment\n\n```\n$ GIT_USER= USE_SSH=true yarn deploy\n```\n\nIf you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.\n\n## Contributing\n\n### Writing/fixing docs\n\nFeel free to open an issue/a PR if you find something weird in the docs.\n\nYour PR once submitted to us, will automatically deploy to a temporary Netlify instance for us or you to review through GitHub's CI/CD checks: you will be able to click on a preview link once the build is ready.\n\n### Internationalization (i18n)\n\nWe're working with Crowdin to manage translations, if you feel like you want to lend a hand for translations, take a look at the documentation project: https://tauri.crowdin.com/documentation\n\nTo add a language to the site, add it to `docusaurus.config.js`'s `siteconfig.i18n.locales` object.\n\nThe following items should be translated before enabling a language:\n\n- strings in i18n/[language] json files\n- docs/about/intro.md and docs/about/security.md;\n- all files in docs/getting-started;\n- all files in docs/development;\n\n\n\n## License\n\nMIT License\n\nCopyright (c) 2020-2021 Tauri Programme within The Commons Conservancy\n","url":"https://github.com/tauri-apps/tauri-docs"},{"id":"github_tauri_apps_tauri_vscode","name":"tauri-vscode","description":"Visual Studio Code Extension for Tauri apps development","kind":"unknown","stars":47,"watchers":47,"subscribers":10,"openIssues":5,"forks":4,"defaultBranch":"dev","language":"TypeScript","topics":[],"isTemplate":false,"lastUpdated":"2022-02-11T13:02:49Z","createdAt":"2020-07-06T16:20:49Z","text":"# Tauri VS Code Extension\n\nVisual Studio Code Extension that adds support to Tauri commands and `tauri.conf.json` JSON validation.\n\n## Supported commands\n\nIt adds the `init`, `deps`, `dev` and `build` commands to the `Command Palette`.\n\n## JSON validation\n\nThe extension automatically pulls the [latest config schema](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli/schema.json) so VS Code can display documentation and autocomplete.\n\n# Contributing\n\nFollowing [the official guide](https://code.visualstudio.com/api/get-started/your-first-extension), run `yarn` to install dependencies, `yarn compile` to build your changes and press `F5` to open a new `Extension Development Host` window.\n","url":"https://github.com/tauri-apps/tauri-vscode"},{"id":"github_tauri_apps_tauri_plugin_upload","name":"tauri-plugin-upload","description":"Tauri plugin for file uploads through HTTP","kind":"plugin","stars":2,"watchers":2,"subscribers":8,"openIssues":5,"forks":1,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2021-12-15T22:05:39Z","createdAt":"2021-10-01T16:11:09Z","license":"Other","text":"# Tauri Plugin Upload\n![Test](https://github.com/tauri-apps/tauri-plugin-upload/workflows/Test/badge.svg)\n\nThis plugin provides an interface for file uploads.\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition.\n\n### `/webview-src`\nTypescript source for the /webview-dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a Tauri application.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the example app](examples/svelte-app). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-upload]\ngit = \"https://github.com/tauri-apps/tauri-plugin-upload\"\ntag = \"v0.1.0\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_upload::Upload;\n\nfn main() {\n tauri::Builder::default()\n .plugin(Upload::default())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-upload#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-upload#v0.1.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-upload#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n# or\nyarn add github:tauri-apps/tauri-plugin-upload#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-upload-api\": \"github:tauri-apps/tauri-plugin-upload#v0.1.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport upload from 'tauri-plugin-upload-api'\nawait upload('/path/to/file')\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-upload"},{"id":"github_tauri_apps_tauri_plugin_window_state","name":"tauri-plugin-window-state","description":null,"kind":"plugin","stars":5,"watchers":5,"subscribers":8,"openIssues":4,"forks":0,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-01-23T02:29:35Z","createdAt":"2021-09-26T04:49:19Z","license":"Other","text":"# Tauri Plugin Window State\n![Test](https://github.com/tauri-apps/tauri-plugin-window-state/workflows/Test/badge.svg)\n\nThis plugin provides a Tauri Plugin that saves the window position and size and restores it when the app is reopened.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the vanilla demo](examples/vanilla/src-tauri/src/main.rs).\nPlease note, below in the dependencies you can also lock to a revision/tag in the `Cargo.toml`.\n\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri]\ngit = \"https://github.com/tauri-apps/tauri/\"\nbranch = \"next\"\nfeatures = [\"api-all\"]\n\n[dependencies.tauri-plugin-window-state]\ngit = \"https://github.com/tauri-apps/tauri-plugin-window-state\"\ntag = \"tauri-plugin-window-state-v0.1.0\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nfn main() {\n tauri::Builder::default()\n .plugin(tauri_plugin_window_state::WindowState::default())\n .run();\n}\n```\n\nTo prevent flashes when the window is updated, the window `visible` property must be set to `false`.\nThe plugin is responsible for showing it after restoring its state.\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-window-state"},{"id":"github_tauri_apps_tauri_plugin_store","name":"tauri-plugin-store","description":"This plugin provides an interface for storing unencrypted values on the application cache folder.","kind":"plugin","stars":16,"watchers":16,"subscribers":8,"openIssues":3,"forks":3,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-10T15:05:00Z","createdAt":"2021-09-27T16:10:02Z","license":"Other","text":"# Tauri Plugin Store\n[![devto](https://img.shields.io/badge/documentation-github.io-purple.svg)](https://tauri-apps.github.io/tauri-plugin-store)\n![Test](https://github.com/tauri-apps/tauri-plugin-store/workflows/Test/badge.svg)\n\nThis plugin provides an interface for storing unencrypted values on the application cache folder.\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition.\n\n### `/webview-src`\nTypescript source for the /webview-dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a Tauri application.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the example app](examples/svelte-app). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-store]\ngit = \"https://github.com/tauri-apps/tauri-plugin-store\"\ntag = \"v0.1.0\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_store::PluginBuilder;\n\nfn main() {\n tauri::Builder::default()\n .plugin(PluginBuilder::default())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-store#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-store#v0.1.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-store#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n# or\nyarn add github:tauri-apps/tauri-plugin-store#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-store-api\": \"github:tauri-apps/tauri-plugin-store#v0.1.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport { Store } from 'tauri-plugin-store-api'\nconst store = new Store('.settings.dat')\nawait store.set('some-key', { value: 5 })\nconst val = await store.get('some-key')\nassert(val, { value: 5 })\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-store"},{"id":"github_tauri_apps_tauri_plugin_websocket","name":"tauri-plugin-websocket","description":null,"kind":"plugin","stars":5,"watchers":5,"subscribers":8,"openIssues":6,"forks":0,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-01-30T04:52:31Z","createdAt":"2021-09-14T23:49:58Z","text":"","url":"https://github.com/tauri-apps/tauri-plugin-websocket"},{"id":"github_tauri_apps_tauri_plugin_fs_extra","name":"tauri-plugin-fs-extra","description":"Tauri plugin that adds file system methods that aren't included in the core API","kind":"plugin","stars":4,"watchers":4,"subscribers":8,"openIssues":4,"forks":0,"defaultBranch":"dev","language":"TypeScript","topics":[],"isTemplate":false,"lastUpdated":"2021-11-19T14:46:36Z","createdAt":"2021-10-19T15:18:57Z","license":"Other","text":"# tauri-plugin-fs-extra\n![Test](https://github.com/tauri-apps/tauri-plugin-fs-extra/workflows/Test/badge.svg)\n\nThis plugin provides a \"classical\" Tauri Plugin Interface that adds file system methods that aren't included in the Tauri core API.\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition.\n\n### `/webview-src`\nTypescript source for the /webview-dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a Tauri application.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the Todo app](examples/todos-app/). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-fs-extra]\ngit = \"https://github.com/tauri-apps/tauri-plugin-fs-extra\"\ntag = \"v0.1.0\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_fs_extra::FsExtra;\n\nfn main() {\n tauri::Builder::default()\n .plugin(FsExtra::default())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-fs-extra#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-fs-extra#v0.1.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-fs-extra#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n# or\nyarn add github:tauri-apps/tauri-plugin-fs-extra#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-fs-extra-api\": \"github:tauri-apps/tauri-plugin-fs-extra#v0.1.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport { metadata } from 'tauri-plugin-fs-extra-api'\nawait metadata('/path/to/file')\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-fs-extra"},{"id":"github_tauri_apps_tauri_plugin_stronghold","name":"tauri-plugin-stronghold","description":"An official Tauri Plugin for using Stronghold.","kind":"plugin","stars":21,"watchers":21,"subscribers":7,"openIssues":23,"forks":2,"defaultBranch":"main","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-06T02:23:36Z","createdAt":"2021-02-15T12:52:23Z","license":"Other","text":"# Tauri Plugin Stronghold\n![Test](https://github.com/tauri-apps/tauri-plugin-stronghold/workflows/Test/badge.svg)\n\nThis plugin provides a \"classical\" Tauri Plugin Interface to the [IOTA Stronghold](https://github.com/iotaledger/stronghold.rs) encrypted database, secure runtime, and peer-to-peer service.\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition and Stronghold features.\n\n### `/webview-src`\nTypescript source for the /dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a WRY webview.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the svelte demo](examples/svelte-app/src/App.svelte). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-stronghold]\ngit = \"https://github.com/tauri-apps/tauri-plugin-stronghold\"\ntag = \"v0.1.0\"\n#branch = \"main\"\n\n# temporary fix to version resolution\n[patch.crates-io]\naesni = { git = \"https://github.com/RustCrypto/block-ciphers/\", rev = \"268dadc93df08928de3bc510ddf20aabfcc49435\" }\naes-soft = { git = \"https://github.com/RustCrypto/block-ciphers/\", rev = \"268dadc93df08928de3bc510ddf20aabfcc49435\" }\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_stronghold::TauriStronghold;\n\nfn main() {\n tauri::Builder::default()\n .plugin(TauriStronghold {})\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-stronghold#v0.2.0\n# or\nyarn add github:tauri-apps/tauri-plugin-stronghold#v0.2.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-stronghold#6749525a47a95439c9703d3a49b94ac65660998f\n# or\nyarn add github:tauri-apps/tauri-plugin-stronghold#6749525a47a95439c9703d3a49b94ac65660998f\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-stronghold-api\": \"github:tauri-apps/tauri-plugin-stronghold#v0.2.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport { Stronghold, Location } from 'tauri-plugin-stronghold-api'\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-stronghold"},{"id":"github_tauri_apps_tauri_plugin_log","name":"tauri-plugin-log","description":null,"kind":"plugin","stars":9,"watchers":9,"subscribers":9,"openIssues":4,"forks":1,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-01-10T22:29:42Z","createdAt":"2021-09-14T17:58:12Z","license":"Other","text":"# Tauri Plugin Log\n\nThis plugin provides configurable interfaces for capturing and storing logs.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the example app](examples/svelte-app). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-log]\ngit = \"https://github.com/tauri-apps/tauri-plugin-log\"\ntag = \"v0.1.0\"\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-log#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-log#v0.1.0\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-log-api\": \"tauri-apps/tauri-plugin-log#v0.1.0\",\n```\n\n## Usage\n\n### RUST\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_log::{LogTarget, LoggerBuilder};\nfn main() {\n tauri::Builder::default()\n .plugin(LoggerBuilder::new([\n LogTarget::LogDir,\n LogTarget::Stdout,\n LogTarget::Webview,\n ]).build())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n\n```ts\nimport { trace, info, error, attachConsole } from 'tauri-plugin-log-api'\n\n// with LogTarget::Webview enabled this function will print logs to the browser console\nconst detach = await attachConsole()\n\ntrace(\"Trace\")\ninfo(\"Info\")\nerror(\"Error\")\n\n// detach the browser console from the log stream\ndetach()\n```\n","url":"https://github.com/tauri-apps/tauri-plugin-log"},{"id":"github_tauri_apps_tauri_plugin_sql","name":"tauri-plugin-sql","description":null,"kind":"plugin","stars":32,"watchers":32,"subscribers":9,"openIssues":10,"forks":4,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-11T13:59:08Z","createdAt":"2021-09-13T23:51:17Z","license":"Other","text":"# Tauri Plugin SQL\n![Test](https://github.com/tauri-apps/tauri-plugin-sql/workflows/Test/badge.svg)\n\nThis plugin provides a \"classical\" Tauri Plugin Interface to SQL databases through [sqlx](https://github.com/launchbadge/sqlx).\nIt supports the `sqlite`, `mysql` and `postgres` drivers, enabled through a Cargo feature.\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition and `sqlx` features.\n\n### `/webview-src`\nTypescript source for the /webview-dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a Tauri application.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the Todo app](examples/todos-app/). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-sql]\ngit = \"https://github.com/tauri-apps/tauri-plugin-sql\"\ntag = \"v0.1.0\"\nfeatures = [\"sqlite\"] # or \"postgres\", or \"mysql\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_sql::TauriSql;\n\nfn main() {\n tauri::Builder::default()\n .plugin(TauriSql::default())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-sql#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-sql#v0.1.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-sql#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n# or\nyarn add github:tauri-apps/tauri-plugin-sql#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-sql-api\": \"github:tauri-apps/tauri-plugin-sql#v0.1.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport Database from 'tauri-plugin-sql-api'\n\n// sqlite. The path is relative to `tauri::api::path::BaseDirectory::App`.\nconst db = await Database.load('sqlite:test.db')\n// mysql\nconst db = await Database.load('mysql://user:pass@host/database')\n// postgres\nconst db = await Database.load('postgres://postgres:password@localhost/test')\n\nawait db.execute('INSERT INTO ...')\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-sql"},{"id":"github_tauri_apps_tauri_plugin_shadows","name":"tauri-plugin-shadows","description":"Add native shadows to your Tauri/TAO windows.","kind":"plugin","stars":3,"watchers":3,"subscribers":8,"openIssues":1,"forks":0,"defaultBranch":"dev","language":"Rust","topics":["macos","plugin","shadows","tao","tauri","tauri-plugin","windows"],"isTemplate":false,"lastUpdated":"2022-01-24T06:34:53Z","createdAt":"2021-12-30T14:10:26Z","license":"Other","text":"# tauri-plugin-shadows\n\nAdd native shadows to your Tauri/TAO windows.\n\n## Platform support\n\n - **`Windows:`** Yes, but shadows can't be turned off for a normal (decorated) window.\n - **`macOS:`** Yes!\n - **`Linux:`** No, shadows are controlled by the compositor installed on the user system and they can enable it for your app if they want.\n\n## Installation\n\nAdd it as a dependncy in `Cargo.toml` of your Tao/Tauri project\n```toml\n[dependencies]\ntauri-plugin-shadows = { git = \"https://github.com/tauri-apps/tauri-plugin-shadows\", features = [\"tauri-impl\"] } # or \"tao-impl\" for TAO projects.\n```\n\n## Cargo Features:\n\n- `tauri-impl`: for Tauri projects.\n- `tao-impl`: for TAO projects.\n\n## Usage\nImport the `Shadows` trait and use `set_shadow()` on your window type:\n- Tauri:\n ```rs\n let window = app.get_window(\"main\").unwrap();\n\n use tauri_plugin_shadows::Shadows;\n window.set_shadow(true);\n ```\n- Tao:\n ```rs\n let window = WindowBuilder::new().with_transparent(true).build(&event_loop).unwrap();\n\n use tauri_plugin_shadows::Shadows;\n window.set_shadow(true);\n ```","url":"https://github.com/tauri-apps/tauri-plugin-shadows"},{"id":"github_tauri_apps_tauri_plugin_vibrancy","name":"tauri-plugin-vibrancy","description":"Make your Tauri/TAO windows vibrant.","kind":"plugin","stars":12,"watchers":12,"subscribers":8,"openIssues":3,"forks":3,"defaultBranch":"dev","language":"Rust","topics":["acrylic","blur","macos","plugin","tao","tauri","tuari-plugin","vibrancy","windows"],"isTemplate":false,"lastUpdated":"2022-02-07T17:32:38Z","createdAt":"2021-11-30T17:19:44Z","license":"Other","text":"# tauri-plugin-vibrancy\n\nMake your Tauri/TAO windows vibrant.\n\n## Platform support\n\n- **`Windows:`** Yes!\n- **`macOS:`** Yes!\n- **`Linux:`** No, blur effect is controlled by the compositor installed on the user system and they can enable it for your app if they want.\n\n## Installation\n\nAdd it as a dependncy in `Cargo.toml` of your Tao/Tauri project\n```toml\n[dependencies]\ntauri-plugin-vibrancy = { git = \"https://github.com/tauri-apps/tauri-plugin-vibrancy\", features = [\"tauri-impl\"] } # or \"tao-impl\" for TAO projects.\n```\n\n## Cargo Features:\n\n- `tauri-impl`: for Tauri projects.\n- `tao-impl`: for TAO projects.\n\n## Usage\n\n1. Enable transparency on your window:\n - Tauri: Edit your window in `tauri.conf.json > tauri > windows` and add `\"transparent\": true`\n or use `tauri::WindowBuilder::transparent`.\n - TAO: Use `tao::window::WindowBuilder::with_transparent`.\n2. Use the `Vibrancy` trait methods on your window type:\n - Tauri:\n ```rs\n let window = app.get_window(\"main\").unwrap();\n\n use tauri_plugin_vibrancy::Vibrancy;\n #[cfg(target_os = \"windows\")]\n window.apply_blur();\n #[cfg(target_os = \"macos\")]\n {\n use tauri_plugin_vibrancy::MacOSVibrancy;\n window.apply_vibrancy(MacOSVibrancy::AppearanceBased);\n }\n ```\n - Tao:\n ```rs\n let window = WindowBuilder::new().with_transparent(true).build(&event_loop).unwrap();\n\n use tauri_plugin_vibrancy::Vibrancy;\n #[cfg(target_os = \"windows\")]\n window.apply_blur();\n #[cfg(target_os = \"macos\")]\n {\n use tauri_plugin_vibrancy::MacOSVibrancy;\n window.apply_vibrancy(MacOSVibrancy::AppearanceBased);\n }\n ```\n\n## Available methods\n\n> Please read the methods documentation in [src/lib.rs](src/lib.rs)\n- `apply_blur()` - **`Windows`**\n- `apply_acrylic()` - **`Windows`** works on Windows 10 v1809 and above and has bad performance when resizing/dragging the window\n- `apply_vibrancy()` - **`macOS`** thanks to [@youngsing](https://github.com/youngsing)\n\n## TODOS\n\n- [ ] `apply_mica()` for Windows 11\n\n","url":"https://github.com/tauri-apps/tauri-plugin-vibrancy"},{"id":"github_tauri_apps_tauri_plugin_localhost","name":"tauri-plugin-localhost","description":"An official Tauri Plugin for using a localhost server in production apps.","kind":"plugin","stars":5,"watchers":5,"subscribers":8,"openIssues":4,"forks":1,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-01-08T16:29:22Z","createdAt":"2021-11-13T01:45:52Z","text":"# Tauri Plugin Localhost\n","url":"https://github.com/tauri-apps/tauri-plugin-localhost"},{"id":"github_tauri_apps_tauri_plugin_fs_watch","name":"tauri-plugin-fs-watch","description":"A Tauri Plugin to watch the filesystem for changes","kind":"plugin","stars":7,"watchers":7,"subscribers":8,"openIssues":5,"forks":1,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-01-28T07:36:40Z","createdAt":"2021-10-18T16:16:35Z","text":"# Tauri Plugin FSWatch\n![Test](https://github.com/tauri-apps/tauri-plugin-fs-watch/workflows/Test/badge.svg)\n\nThis plugin provides a \"classical\" Tauri Plugin Interface to watch changes on files and directories through [notify](https://github.com/notify-rs/notify).\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition.\n\n### `/webview-src`\nTypescript source for the /webview-dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a Tauri application.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the Todo app](examples/todos-app/). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-fs-watch]\ngit = \"https://github.com/tauri-apps/tauri-plugin-fs-watch\"\ntag = \"v0.1.0\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_fs_watch::Watcher;\n\nfn main() {\n tauri::Builder::default()\n .plugin(Watcher::default())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-fs-watch#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-fs-watch#v0.1.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-fs-watch#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n# or\nyarn add github:tauri-apps/tauri-plugin-fs-watch#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-fs-watch-api\": \"github:tauri-apps/tauri-plugin-fs-watch#v0.1.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport { watch, watchImmediate } from 'tauri-plugin-fs-watch-api'\n\n// can also watch an array of paths\nconst stopWatching = await watch('/path/to/something', { recursive: true }, event => {\n const { type, payload } = event\n})\n\nconst stopRawWatcher = await watchImmediate(['/path/a', '/path/b'], {}, event => {\n const { path, operation, cookie } = event\n})\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-fs-watch"},{"id":"github_tauri_apps_tauri_forage","name":"tauri-forage","description":"Currified localForage with a side of extras.","kind":"unknown","stars":7,"watchers":7,"subscribers":6,"openIssues":6,"forks":2,"defaultBranch":"dev","language":"TypeScript","topics":[],"isTemplate":false,"lastUpdated":"2022-01-17T06:27:39Z","createdAt":"2020-01-15T11:32:27Z","text":"# tauri forage\n![test library](https://github.com/tauri-apps/tauri-forage/workflows/test%20library/badge.svg?branch=dev)\n![npm version](https://img.shields.io/npm/v/@tauri-apps/tauri-forage.svg)\n\n[localForage](https://localforage.github.io/localForage/) is a great way to make sure that you've got the most persistent localStorage available on the device and webview that you are using, but operations (like replacing a keyValue) can be tedious, and our approach of multi-op currying makes it very flexible. It is written and tested in typescript, and ships with commonjs and an ejs versions - as well as all of its own typings in case you are using typescript.\n\nIf you don't know how localForage works, you would do well to check out those docs - because that is the underlying engine that this library uses. But for a refresher, localForage uses IndexedDB, WebSQL, or localStorage - depending on the best engine that the browser offers.\n\n## Installation\n\nInstall with your package manager\n```\nyarn add @tauri-apps/tauri-forage\n```\n\nImport into your JS / TS\n```\nimport { forage } from '@tauri-apps/tauri-forage'\n```\n\nUse it:\n```\nforage.setItem({\n key: 'yourKey',\n value: 'a value'\n})()\n```\n\n## How does it work?\nHere is the `getItem` function. There is a lot to discuss, and once you've understood the principle all of the other functions will make sense to you. If you want to see more details, check out the tests in `test/__tests__/tauriForage.spec.ts`\n\n```ts\ngetItem ({ key, logger, returner, before, store }: BeforeItem = {}) {\n return async function (curry?: MaybeFunction) {\n const storage = await _defineStore({ store: store })\n key = before ? await handler.maybeCurry(curry || null)(key) : key\n return handler.returner(\n storage.getItem(key).then(async (v: any) => {\n return !before ? handler.maybeCurry(curry || null)(v) : v\n }).catch((err: any) => {\n /* istanbul ignore next */\n return handler.logger(err, logger)\n })\n )(returner)\n }\n}\n```\n\nIn its most simple incarnation, you can just get the keyValue of the keyName.\n```\n```\n\n### Returner\nYou can instruct every function to return the value in specific ways.\n\n#### TYPES\n- 1(quiet) - return void 0\n- 2(console) - log the returned value to the console\n- 3(break) - throw an error with the contents of the return\n- 4(truthy) - return a true or false value\n- 5(typeof) - return type of response\n- 6(trace) - get a console.trace() of the call stack\n- 7(passthrough) - the default does nothing to the return\n\n\n### Logger\nIf an error occurs, you can determine how to respond:\n\n#### TYPES\n- 1(none) - just return\n- 2(string) - returned the string value of the error\n- 3(trace) - try to return a stack trace up to the error\n- 4(console) - write a console.error\n- 5(throw) - throw the error\n- 6(default) - return undefined\n\n> If you want, you can also use these handler functions yourself! They are properly exported and typed!\n\n### Currying\nHowever you can also curry the returned value with a function you can pass into the function call.\n\nLet's look at a few tests to see how currying can be applied:\n```ts\nit('will curry after', async () => {\n\n await forage.setItem({\n key: 'user',\n value: { name: 'Alice' }\n } as any)()\n\n const curry = (v: any) => v.toUpperCase()\n\n const user = await forage.getKeyValue({\n key: 'user',\n value: 'name'\n } as any)(curry)\n\n expect(user).toStrictEqual('ALICE')\n})\n```\n\nYou can also curry the value BEFORE it is used by localForage. This example is obviously quite trivial, but you may start to see a pattern emerge.\n```ts\n it('will curry before', async () => {\n\n // you can set objects or arrays or even huge base64 strings for values\n await forage.setItem({\n key: 'user',\n value: {\n name: 'Alice'\n }\n } as any)()\n\n const curry = (v: any) => v.toLowerCase()\n\n const user = await forage.getKeyValue({\n key: 'user',\n value: 'NAME',\n before: true\n } as any)(curry)\n\n expect(user).toStrictEqual('Alice')\n })\n```\n\nIf you want to have multiple \"stores\", you can easily do that too.\n\n\n## Extensions to localForage\nOf note are the extensions to the generic interface:\n - mergeItem (with a number of merge strategies available)\n - getKeyValue\n - deleteItemKey\n - hasKey\n - hasKeyValue\n\n## undefined / void 0 => always returns null!\n> Even if undefined is saved, null will be returned by getItem().\nThis is due to a limitation in localStorage, and for compatibility\nreasons localForage cannot store the value undefined.\n\n# Development\n## Testing\nTests are written with Jasmine flavor using Jest.\n\n## Docs\nThe docs are available as a static site in /docs\n\n## License\n(c) 2019-2020 - Daniel Thompson-Yvetot and contributors\n\nMIT\n","url":"https://github.com/tauri-apps/tauri-forage"},{"id":"github_tauri_apps_tauri_hotkey_rs","name":"tauri-hotkey-rs","description":null,"kind":"code","stars":9,"watchers":9,"subscribers":5,"openIssues":2,"forks":1,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-09T01:52:13Z","createdAt":"2021-02-14T04:49:18Z","text":"# Tauri Hotkey\n\nThis crate provides cross platform APIs to register keyboard hotkeys. This is a fork of [hotkey-rs](https://github.com/gamebooster/soundboard/tree/master/extern/hotkey-rs).\n\n## Platform support\n\n- Linux\n- macOS\n- Windows\n\n## License\nMIT\n","url":"https://github.com/tauri-apps/tauri-hotkey-rs"},{"id":"github_tauri_apps_tauri_dialog_rs","name":"tauri-dialog-rs","description":null,"kind":"unknown","stars":1,"watchers":1,"subscribers":4,"openIssues":0,"forks":1,"defaultBranch":"master","language":"C","topics":[],"isTemplate":false,"lastUpdated":"2021-06-06T00:39:20Z","createdAt":"2020-06-14T10:59:41Z","text":"# tauri-dialog-rs\n\nRust bindings to forked https://github.com/aaronmjacobs/Boxer.\n\n## Deprecation notice\n\nThis crate is no longer maintained. Tauri now uses [rfd](https://github.com/PolyMeilex/rfd).\n","url":"https://github.com/tauri-apps/tauri-dialog-rs"},{"id":"github_tauri_apps_tauri_inliner_rs","name":"tauri-inliner-rs","description":null,"kind":"code","stars":0,"watchers":0,"subscribers":4,"openIssues":2,"forks":0,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2021-04-12T08:30:46Z","createdAt":"2020-12-12T13:20:34Z","license":"MIT License","text":"# Tauri Inliner\n\nA Rust library for inlining assets in an HTML file. Based on the work on [inline-assets-rs](https://github.com/8176135/inline-assets-rs) and [inliner](https://github.com/remy/inliner).\n","url":"https://github.com/tauri-apps/tauri-inliner-rs"},{"id":"github_tauri_apps_tauri_inliner_rs","name":"tauri-inliner-rs","description":null,"kind":"code","stars":0,"watchers":0,"subscribers":4,"openIssues":2,"forks":0,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2021-04-12T08:30:46Z","createdAt":"2020-12-12T13:20:34Z","license":"MIT License","text":"# Tauri Inliner\n\nA Rust library for inlining assets in an HTML file. Based on the work on [inline-assets-rs](https://github.com/8176135/inline-assets-rs) and [inliner](https://github.com/remy/inliner).\n","url":"https://github.com/tauri-apps/tauri-inliner-rs"},{"id":"github_tauri_apps_rfcs","name":"rfcs","description":"A medium for proposing and repo of accepted RFCs.","kind":"unknown","stars":12,"watchers":12,"subscribers":6,"openIssues":1,"forks":1,"defaultBranch":"master","language":null,"topics":[],"isTemplate":false,"lastUpdated":"2021-07-16T22:50:55Z","createdAt":"2020-03-10T14:53:02Z","text":"# Tauri RFC Repository\nThis repo is dedicated to an RFC process, through which we have significant changes to the project undergo a transparent consideration and confirm changes by accepting them into the repo.\n\n## Process\n1) **Start a discussion.** Writing an RFC is a large investment of time, it's best to discuss it with the community to be sure it's worthwhile and to get it done right.\n2) **Fork this repo.** The review period of RFCs is held in the PR back into the repo.\n3) **Copy the template.** Move your copy of `template.md` into the `texts` folder, naming it in the scheme of `0000-feature.md`. Note: the number is literal, it needs to be adjusted just before merging.\n4) **Fill the template out.** Replace all relevant sections with explanations. Put care into the details, as it will serve as a reference through the development process.\n5) **Open a PR.** At this point, the RFC is open for comment. Discussion should happen in the comments of the PR. RFCs that are \"invalid\" (don't follow the format/proceedure, violate CoC, or are otherwise unable to be used) may be closed immediately, otherwise they will be left open for a minimum of 2 weeks before being accepted or rejected.\n6) **After the comment period,** a member of the Core Team will handle closing the RFC. If accepted, the RFC will be assigned a number and a tracking issue opened on the appropriate repo. Both details will be added to the RFC, then the PR will be merged.\n","url":"https://github.com/tauri-apps/rfcs"},{"id":"github_tauri_apps_tauri_theia","name":"tauri-theia","description":"Tauri Flavor of Theia","kind":"code","stars":28,"watchers":28,"subscribers":5,"openIssues":7,"forks":4,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2021-12-01T07:36:59Z","createdAt":"2020-05-09T18:07:35Z","license":"MIT License","text":"# Tauri Theia\n\n[Theia IDE](https://theia-ide.org/) packaged as a Tauri application.\n\n## To Use\n\nCurrently only working in Linux\n\n1. Clone this repository and open a terminal in the root of it. Make sure to use Node v10.x\n2. Install deps with `yarn`\n3. Package Theia server as an executable with `yarn theia:package`\n4. Run `yarn tauri build` to build the executable\n","url":"https://github.com/tauri-apps/tauri-theia"},{"id":"github_tauri_apps_tauri_toml","name":"tauri-toml","description":"Better TOML parsing and stringifying all in that familiar JSON interface.","kind":"unknown","stars":0,"watchers":0,"subscribers":1,"openIssues":0,"forks":1,"defaultBranch":"dev","language":"JavaScript","topics":[],"isTemplate":false,"lastUpdated":"2019-12-15T20:14:20Z","createdAt":"2019-11-30T11:18:10Z","license":"ISC License","text":"# @tauri-apps/toml\n\n## This is a fork of iarna-toml so that we can make some needed modifations for `tauri`.\n\nBetter TOML parsing and stringifying all in that familiar JSON interface.\n\n[![Coverage Status](https://coveralls.io/repos/github/iarna/iarna-toml/badge.svg)](https://coveralls.io/github/iarna/iarna-toml)\n\n# ** TOML 0.5.0 **\n\n### TOML Spec Support\n\nThe most recent version as of 2018-07-26: [v0.5.0](https://github.com/mojombo/toml/blob/master/versions/en/toml-v0.5.0.md)\n\n### Example\n\n```js\nconst TOML = require('@tauri-apps/toml')\nconst obj = TOML.parse(`[abc]\nfoo = 123\nbar = [1,2,3]`)\n/* obj =\n{abc: {foo: 123, bar: [1,2,3]}}\n*/\nconst str = TOML.stringify(obj)\n/* str =\n[abc]\nfoo = 123\nbar = [ 1, 2, 3 ]\n*/\n```\n\nVisit the project github [for more examples](https://github.com/iarna/iarna-toml/tree/latest/examples)!\n\n\n## Why @tauri-apps/toml\n\n* See [TOML-SPEC-SUPPORT](https://shared.by.re-becca.org/misc/TOML-SPEC-SUPPORT.html) for a comparison of which TOML features\n are supported by the various Node.js TOML parsers.\n* BigInt support on Node 10!\n* 100% test coverage.\n* Faster parsing, even if you only use TOML 0.4.0, it's as much as 100 times\n faster than `toml` and 3 times faster than `toml-j0.4`. However a recent\n newcomer [`@ltd/j-toml`](https://www.npmjs.com/package/@ltd/j-toml) has\n appeared with 0.5 support and astoundingly fast parsing speeds for large\n text blocks. All I can say is you'll have to test your specific work loads\n if you want to know which of @tauri-apps/toml and @ltd/j-toml is faster for\n you, as we currently excell in different areas\n* Careful adherence to spec. Tests go beyond simple coverage.\n* Smallest parser bundle (if you use `@tauri-apps/toml/parse-string`).\n* No deps.\n* Detailed and easy to read error messages‼\n\n```console\n> TOML.parse(src)\nError: Unexpected character, expecting string, number, datetime, boolean, inline array or inline table at row 6, col 5, pos 87:\n5: \"abc\\\"\" = { abc=123,def=\"abc\" }\n6> foo=sdkfj\n ^\n7:\n```\n\n## TOML.parse(str) → Object [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse.js)\n\nAlso available with: `require('@tauri-apps/toml/parse-string')`\n\nSynchronously parse a TOML string and return an object.\n\n\n## TOML.stringify(obj) → String [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/stringify.js)\n\nAlso available with: `require('@tauri-apps/toml/stringify)`\n\nSerialize an object as TOML.\n\n## [your-object].toJSON\n\nIf an object `TOML.stringify` is serializing has a `toJSON` method then it\nwill call it to transform the object before serializing it. This matches\nthe behavior of `JSON.stringify`.\n\nThe one exception to this is that `toJSON` is not called for `Date` objects\nbecause `JSON` represents dates as strings and TOML can represent them natively.\n\n[`moment`](https://www.npmjs.com/package/moment) objects are treated the\nsame as native `Date` objects, in this respect.\n\n## TOML.stringify.value(obj) -> String\n\nAlso available with: `require('@tauri-apps/toml/stringify').value`\n\nSerialize a value as TOML would. This is a fragment and not a complete\nvalid TOML document.\n\n## Promises and Streaming\n\nThe parser provides alternative async and streaming interfaces, for times\nthat you're working with really absurdly big TOML files and don't want to\ntie-up the event loop while it parses.\n\n### TOML.parse.async(str[, opts]) → Promise(Object) [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse-async.js)\n\nAlso available with: `require('@tauri-apps/toml/parse-async')`\n\n`opts.blocksize` is the amount text to parser per pass through the event loop. Defaults to 40kb.\n\nAsynchronously parse a TOML string and return a promise of the resulting object.\n\n### TOML.parse.stream(readable) → Promise(Object) [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse-stream-readable.js)\n\nAlso available with: `require('@tauri-apps/toml/parse-stream')`\n\nGiven a readable stream, parse it as it feeds us data. Return a promise of the resulting object.\n\n### readable.pipe(TOML.parse.stream()) → Transform [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse-stream-through.js)\n\nAlso available with: `require('@tauri-apps/toml/parse-stream')`\n\nReturns a transform stream in object mode. When it completes, emit the\nresulting object. Only one object will ever be emitted.\n\n## Lowlevel Interface [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse-lowlevel.js) [(example w/ parser debugging)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse-lowlevel-debug.js)\n\nYou construct a parser object, per TOML file you want to process:\n\n```js\nconst TOMLParser = require('@tauri-apps/toml/lib/toml-parser.js')\nconst parser = new TOMLParser()\n```\n\nThen you call the `parse` method for each chunk as you read them, or in a\nsingle call:\n\n```js\nparser.parse(`hello = 'world'`)\n```\n\nAnd finally, you call the `finish` method to complete parsing and retrieve\nthe resulting object.\n\n```js\nconst data = parser.finish()\n```\n\nBoth the `parse` method and `finish` method will throw if they find a\nproblem with the string they were given. Error objects thrown from the\nparser have `pos`, `line` and `col` attributes. `TOML.parse` adds a visual\nsummary of where in the source string there were issues using\n`parse-pretty-error` and you can too:\n\n```js\nconst prettyError = require('./parse-pretty-error.js')\nconst newErr = prettyError(err, sourceString)\n```\n\n## What's Different\n\nVersion 2 of this module supports TOML 0.5.0. Other modules currently\npublished to the npm registry support 0.4.0. 0.5.0 is mostly backwards\ncompatible with 0.4.0, but if you have need, you can install @tauri-apps/toml@1\nto get a version of this module that supports 0.4.0. Please see the\n[CHANGELOG](CHANGELOG.md#2.0.0) for details on exactly whats changed.\n\n## TOML we can't do\n\n* `-nan` is a valid TOML value and is converted into `NaN`. There is no way to\n produce `-nan` when stringifying. Stringification will produce positive `nan`.\n* Detecting and erroring on invalid utf8 documents: This is because Node's\n UTF8 processing converts invalid sequences into the placeholder character\n and does not have facilities for reporting these as errors instead. We\n _can_ detect the placeholder character, but it's valid to intentionally\n include them in documents, so erroring on them is not great.\n* On versions of Node < 10, very large Integer values will lose precision.\n On Node >=10, bigints are used.\n* Floating/local dates and times are still represented by JavaScript Date\n objects, which don't actually support these concepts. The objects\n returned have been modified so that you can determine what kind of thing\n they are (with `isFloating`, `isDate`, `isTime` properties) and that\n their ISO representation (via `toISOString`) is representative of their\n TOML value. They will correctly round trip if you pass them to\n `TOML.stringify`.\n* Binary, hexadecimal and octal values are converted to ordinary integers and\n will be decimal if you stringify them.\n\n## Changes\n\nI write a by hand, honest-to-god,\n[CHANGELOG](https://github.com/iarna/iarna-toml/blob/latest/CHANGELOG.md)\nfor this project. It's a description of what went into a release that you\nthe consumer of the module could care about, not a list of git commits, so\nplease check it out!\n\n## Benchmarks\n\nYou can run them yourself with:\n\n```console\n$ npm run benchmark\n```\n\nThe results below are from my laptop using Node 11.10.0. The library\nversions tested were `@tauri-apps/toml@2.2.2`, `toml-j0.4@1.1.1`, `toml@3.0.0`,\n`@sgarciac/bombadil@2.1.0` and `@ltd/j-toml@0.5.47`. The speed value is\nmegabytes-per-second that the parser can process of that document type.\nBigger is better. The percentage after average results is the margin of error.\n\nAs this table is getting a little wide, with how npm and github display it,\nyou can also view it seperately in the [BENCHMARK](https://shared.by.re-becca.org/misc/BENCHMARK.html) document.\n\n| | @tauri-apps/toml | | toml-j0.4 | | toml | | @sgarciac/bombadil | | @ltd/j-toml | |\n| - | ----------- | - | --------- | - | ---- | - | ------------------ | - | ----------- | - |\n| Overall | 25MB/sec | 0.55% | 7MB/sec | 1.39% | 0.2MB/sec | 3.47% | - | - | 38MB/sec | 1.37% |\n| Spec Example: v0.4.0 | 23MB/sec | 0.87% | 10MB/sec | 0.62% | 1MB/sec | 1.89% | 1.7MB/sec | 1.03% | 35MB/sec | 1.32% |\n| Spec Example: Hard Unicode | 57MB/sec | 1.46% | 16MB/sec | 0.66% | 2MB/sec | 2.25% | 0.8MB/sec | 0.57% | 93MB/sec | 1.79% |\n| Types: Array, Inline | 7.2MB/sec | 1.60% | 3.2MB/sec | 0.77% | 0.1MB/sec | 1.84% | 1.7MB/sec | 0.56% | 4.1MB/sec | 14.48% |\n| Types: Array | 6.9MB/sec | 0.47% | 5.8MB/sec | 0.46% | 0.1MB/sec | 3.67% | 1.4MB/sec | 0.76% | 2.5MB/sec | 8.19% |\n| Types: Boolean, | 22MB/sec | 0.85% | 8.5MB/sec | 0.55% | 0.2MB/sec | 1.83% | 2.1MB/sec | 1.29% | 5.6MB/sec | 0.58% |\n| Types: Datetime | 18MB/sec | 0.56% | 11MB/sec | 0.80% | 0.3MB/sec | 1.55% | 0.8MB/sec | 0.51% | 4.5MB/sec | 0.66% |\n| Types: Float | 9.2MB/sec | 0.71% | 5.2MB/sec | 1.12% | 0.3MB/sec | 2.04% | 2.6MB/sec | 0.86% | 3.7MB/sec | 0.61% |\n| Types: Int | 6.4MB/sec | 0.44% | 3.9MB/sec | 0.56% | 0.1MB/sec | 1.65% | 1.7MB/sec | 1.15% | 1.5MB/sec | 4.06% |\n| Types: Literal String, 7 char | 26MB/sec | 0.62% | 8.1MB/sec | 1.00% | 0.3MB/sec | 1.48% | 2.9MB/sec | 0.58% | 6MB/sec | 0.52% |\n| Types: Literal String, 92 char | 41MB/sec | 0.80% | 11MB/sec | 1.20% | 0.4MB/sec | 2.38% | 15MB/sec | 0.84% | 23MB/sec | 0.58% |\n| Types: Literal String, Multiline, 1079 char | 21MB/sec | 0.28% | 7.2MB/sec | 1.62% | 1.3MB/sec | 3.05% | 55MB/sec | 0.53% | 332MB/sec | 0.46% |\n| Types: Basic String, 7 char | 26MB/sec | 0.56% | 6.6MB/sec | 0.61% | 0.2MB/sec | 4.70% | 2.7MB/sec | 0.68% | 3.3MB/sec | 0.47% |\n| Types: Basic String, 92 char | 41MB/sec | 0.63% | 8MB/sec | 0.51% | 0.1MB/sec | 1.57% | 14MB/sec | 0.66% | 21MB/sec | 0.43% |\n| Types: Basic String, 1079 char | 21MB/sec | 0.36% | 6MB/sec | 0.81% | 0.1MB/sec | 1.81% | 51MB/sec | 0.53% | 13MB/sec | 0.62% |\n| Types: Table, Inline | 9.8MB/sec | 0.47% | 4.6MB/sec | 0.81% | 0.1MB/sec | 1.82% | 1.7MB/sec | 0.75% | 2.9MB/sec | 4.82% |\n| Types: Table | 6.9MB/sec | 0.43% | 4.9MB/sec | 0.46% | 0.1MB/sec | 3.59% | 1.6MB/sec | 0.88% | 4.4MB/sec | 0.53% |\n| Scaling: Array, Inline, 1000 elements | 33MB/sec | 2.15% | 2.5MB/sec | 1.07% | 0.1MB/sec | 3.57% | 1.8MB/sec | 0.64% | 8.7MB/sec | 4.12% |\n| Scaling: Array, Nested, 1000 deep | 1.6MB/sec | 2.50% | 1.2MB/sec | 0.49% | 0.1MB/sec | 3.62% | - | - | 1MB/sec | 3.79% |\n| Scaling: Literal String, 40kb | 56MB/sec | 0.58% | 12MB/sec | 1.03% | 3.6MB/sec | 4.00% | 17MB/sec | 0.54% | 498MB/sec | 0.52% |\n| Scaling: Literal String, Multiline, 40kb | 58MB/sec | 0.38% | 6.4MB/sec | 0.54% | 0.2MB/sec | 1.72% | 15MB/sec | 0.74% | 197MB/sec | 0.54% |\n| Scaling: Basic String, Multiline, 40kb | 57MB/sec | 1.03% | 7.2MB/sec | 1.22% | 3.4MB/sec | 4.24% | 15MB/sec | 0.75% | 840MB/sec | 0.52% |\n| Scaling: Basic String, 40kb | 57MB/sec | 0.43% | 8.6MB/sec | 0.57% | 0.2MB/sec | 1.71% | 17MB/sec | 0.51% | 394MB/sec | 0.54% |\n| Scaling: Table, Inline, 1000 elements | 27MB/sec | 0.46% | 7.5MB/sec | 0.71% | 0.3MB/sec | 2.24% | 3MB/sec | 0.74% | 2.3MB/sec | 0.81% |\n| Scaling: Table, Inline, Nested, 1000 deep | 7.8MB/sec | 0.61% | 4.3MB/sec | 0.83% | 0.1MB/sec | 2.93% | - | - | 1.2MB/sec | 13.45% |\n\n## Tests\n\nThe test suite is maintained at 100% coverage: [![Coverage Status](https://coveralls.io/repos/github/iarna/iarna-toml/badge.svg)](https://coveralls.io/github/iarna/iarna-toml)\n\nThe spec was carefully hand converted into a series of test framework\nindependent (and mostly language independent) assertions, as pairs of TOML\nand YAML files. You can find those files here:\n[spec-test](https://github.com/iarna/iarna-toml/blob/latest/test/spec-test/).\nA number of examples of invalid Unicode were also written, but are difficult\nto make use of in Node.js where Unicode errors are silently hidden. You can\nfind those here: [spec-test-disabled](https://github.com/iarna/iarna-toml/blob/latest/test/spec-test-disabled/).\n\nFurther tests were written to increase coverage to 100%, these may be more\nimplementation specific, but they can be found in [coverage](https://github.com/iarna/iarna-toml/blob/latest/test/coverage.js) and\n[coverage-error](https://github.com/iarna/iarna-toml/blob/latest/test/coverage-error.js).\n\nI've also written some quality assurance style tests, which don't contribute\nto coverage but do cover scenarios that could easily be problematic for some\nimplementations can be found in:\n[test/qa.js](https://github.com/iarna/iarna-toml/blob/latest/test/qa.js) and\n[test/qa-error.js](https://github.com/iarna/iarna-toml/blob/latest/test/qa-error.js).\n\nAll of the official example files from the TOML spec are run through this\nparser and compared to the official YAML files when available. These files are from the TOML spec as of:\n[357a4ba6](https://github.com/toml-lang/toml/tree/357a4ba6782e48ff26e646780bab11c90ed0a7bc)\nand specifically are:\n\n* [github.com/toml-lang/toml/tree/357a4ba6/examples](https://github.com/toml-lang/toml/tree/357a4ba6782e48ff26e646780bab11c90ed0a7bc/examples)\n* [github.com/toml-lang/toml/tree/357a4ba6/tests](https://github.com/toml-lang/toml/tree/357a4ba6782e48ff26e646780bab11c90ed0a7bc/tests)\n\nThe stringifier is tested by round-tripping these same files, asserting that\n`TOML.parse(sourcefile)` deepEqual\n`TOML.parse(TOML.stringify(TOML.parse(sourcefile))`. This is done in\n[test/roundtrip-examples.js](https://github.com/iarna/iarna-toml/blob/latest/test/round-tripping.js)\nThere are also some tests written to complete coverage from stringification in:\n[test/stringify.js](https://github.com/iarna/iarna-toml/blob/latest/test/stringify.js)\n\nTests for the async and streaming interfaces are in [test/async.js](https://github.com/iarna/iarna-toml/blob/latest/test/async.js) and [test/stream.js](https://github.com/iarna/iarna-toml/blob/latest/test/stream.js) respectively.\n\nTests for the parsers debugging mode live in [test/devel.js](https://github.com/iarna/iarna-toml/blob/latest/test/devel.js).\n\nAnd finally, many more stringification tests were borrowed from [@othiym23](https://github.com/othiym23)'s\n[toml-stream](https://npmjs.com/package/toml-stream) module. They were fetched as of\n[b6f1e26b572d49742d49fa6a6d11524d003441fa](https://github.com/othiym23/toml-stream/tree/b6f1e26b572d49742d49fa6a6d11524d003441fa/test) and live in\n[test/toml-stream](https://github.com/iarna/iarna-toml/blob/latest/test/toml-stream/).\n\n## Improvements to make\n\n* In stringify:\n * Any way to produce comments. As a JSON stand-in I'm not too worried\n about this. That said, a document orientated fork is something I'd like\n to look at eventually…\n * Stringification could use some work on its error reporting. It reports\n _what's_ wrong, but not where in your data structure it was.\n* Further optimize the parser:\n * There are some debugging assertions left in the main parser, these should be moved to a subclass.\n * Make the whole debugging parser thing work as a mixin instead of as a superclass.\n","url":"https://github.com/tauri-apps/tauri-toml"},{"id":"github_tauri_apps_realworld","name":"realworld","description":"Realworld apps made with Tauri: Proof of Agnosis.","kind":"unknown","stars":4,"watchers":4,"subscribers":5,"openIssues":1,"forks":0,"defaultBranch":"dev","language":"JavaScript","topics":[],"isTemplate":false,"lastUpdated":"2021-03-02T14:54:39Z","createdAt":"2020-02-05T22:02:37Z","license":"MIT License","text":"# Tauri x Realworld apps\n\nThis project is an experiment to demonstrate how easy you can bundle an existing frontend app with Tauri, whichever the framework you're using, without having to change a single line from the codebase.\n\nThe main script (build.js) simply consists in a pipeline that will clone, install dependencies, build the application, initialize Tauri then bundle the application. \n\n## Setup\n\n1. Take a look at the Wiki to setup Tauri: https://github.com/tauri-apps/tauri/wiki\n2. Have Git, Node and NPM installed\n3. Clone and install this project dependencies, either with NPM or Yarn:\n```bash\ngit clone git@github.com:tauri-apps/realworld.git\ncd realworld\n\nyarn install\n# OR\nnpm install\n```\n\n## Usage\n\n`node build {{app.repo}}`\nThis will apply the pipeline on a single application from apps.yaml. Copy/paste a `repo` property from the wanted application and let it build.\n\n`node build`\nThis will apply the pipeline on _every_ application from apps.yaml. Unless you have some spare time, enough disk space, a nice CPU and unlimited bandwidth, you should avoid to do it (and ensure the pipeline at least works for a single project in a first time).\n\n## Details about apps.yaml\n\nCommented apps have not been successfully bundled (yet), either because of the build or the bundle phase failing.\nA detail about what's wrong is displayed above the app title. \n","url":"https://github.com/tauri-apps/realworld"},{"id":"github_tauri_apps_governance_and_guidance","name":"governance-and-guidance","description":null,"kind":"unknown","stars":3,"watchers":3,"subscribers":16,"openIssues":7,"forks":2,"defaultBranch":"master","language":null,"topics":[],"isTemplate":false,"lastUpdated":"2021-03-15T09:00:16Z","createdAt":"2019-09-04T18:07:56Z","license":"MIT License","text":"# Governance and Guidance\n","url":"https://github.com/tauri-apps/governance-and-guidance"},{"id":"github_tauri_apps_tauri_search_bot","name":"tauri-search-bot","description":"Tauri's Discord Bot","kind":"unknown","stars":1,"watchers":1,"subscribers":4,"openIssues":10,"forks":0,"defaultBranch":"main","language":"JavaScript","topics":[],"isTemplate":false,"lastUpdated":"2021-08-09T07:21:36Z","createdAt":"2021-02-09T21:05:37Z","license":"MIT License","text":"# tauri-search-bot","url":"https://github.com/tauri-apps/tauri-search-bot"},{"id":"github_tauri_apps_webkit_gtk_rs","name":"webkit2gtk-rs","description":"WebKit2 bindings and wrappers for Rust","kind":"code","stars":77,"watchers":77,"subscribers":12,"openIssues":13,"forks":21,"defaultBranch":"crate","language":"Rust","topics":["hacktoberfest"],"isTemplate":false,"lastUpdated":"2022-01-06T06:45:42Z","createdAt":"2016-09-14T17:22:14Z","license":"MIT License","text":"# webkit2gtk\n\n__Rust__ bindings and wrappers for __webkit2gtk__.\n\n## Building\n\n__webkit2gtk-rs__ expects __GTK+__, __GLib__ and __webkit2gtk__ development files to be installed on your system.\nSee the [requirements page](http://gtk-rs.org/docs/requirements.html).\n\n## Using\n\n```toml\n[dependencies]\nwebkit2gtk-rs = \"0.15\"\n```\n\n## License\n\n__webkit2gtk-rs__ is available under the MIT License, please refer to it.\n","url":"https://github.com/tauri-apps/webkit2gtk-rs"},{"id":"github_tauri_apps_javascriptcore_rs","name":"javascriptcore-rs","description":"JavaScriptCore bindings and wrappers for Rust","kind":"code","stars":32,"watchers":32,"subscribers":11,"openIssues":1,"forks":16,"defaultBranch":"crate","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-03T18:39:42Z","createdAt":"2016-09-18T21:14:54Z","license":"MIT License","text":"# javascriptcore\n\n__Rust__ bindings and wrappers for __javascriptcore__.\n\n## Using\n\n```toml\n[dependencies]\njavascriptcore-rs = \"0.14\"\n```\n\n## License\n\n__javascriptcore-rs__ is available under the MIT License, please refer to it.\n","url":"https://github.com/tauri-apps/javascriptcore-rs"},{"id":"github_tauri_apps_awesome_tauri","name":"awesome-tauri","description":"🚀 Awesome Tauri Apps, Plugins and Resources","kind":"unknown","stars":59,"watchers":59,"subscribers":12,"openIssues":1,"forks":7,"defaultBranch":"dev","language":null,"topics":["awesome","awesome-list","tauri"],"isTemplate":false,"lastUpdated":"2022-02-11T17:37:37Z","createdAt":"2022-01-22T16:25:58Z","license":"MIT License","text":"\n\n

Awesome Tauri

\n\n

\nThis is where we collect all of the best stuff from the ecosystem and community.\n

\n\n\nAwesome\n\n

\n\n## Table of Contents\n- [Get Started](#get-started)\n- [Plugins](#plugins)\n- [Integrations](#integrations)\n- [Apps](#apps)\n- [Tutorials](#tutorials)\n- [Articles](#articles)\n\n## Get Started\n\n- [Introduction](https://tauri.studio/docs/development/intro) - Official introduction to Tauri.\n- [create-tauri-app](https://github.com/tauri-apps/tauri/tree/next/tooling/create-tauri-app) - Rapidly scaffold your Tauri app.\n\n### Templates\n- [tauri-svelte-template](https://github.com/probablykasper/tauri-svelte-template) - Svelte template with cross-platform GitHub action builds, macOS 10.13+ support, Vite, TypeScript, Svelte Preprocess, hot module replacement, ESLint and Prettier.\n\n## Plugins\n\n- [tauri-plugin-authenticator](https://github.com/tauri-apps/tauri-plugin-authenticator) ![official](https://img.shields.io/badge/-official-FFC131) - Interface with hardware security keys.\n- [tauri-plugin-log](https://github.com/tauri-apps/tauri-plugin-log) ![official](https://img.shields.io/badge/-official-FFC131) - Configurable logging.\n- [tauri-plugin-sql](https://github.com/tauri-apps/tauri-plugin-sql) ![official](https://img.shields.io/badge/-official-FFC131) - Interface with SQL databases.\n- [tauri-plugin-store](https://github.com/tauri-apps/tauri-plugin-store) ![official](https://img.shields.io/badge/-official-FFC131) - Persistent key value storage.\n- [tauri-plugin-stronghold](https://github.com/tauri-apps/tauri-plugin-stronghold) ![official](https://img.shields.io/badge/-official-FFC131) - Encrypted, secure, p2p database.\n- [tauri-plugin-window-state](https://github.com/tauri-apps/tauri-plugin-window-state) ![official](https://img.shields.io/badge/-official-FFC131) - Persist window sizes and positions.\n- [tauri-plugin-vibrancy](https://github.com/tauri-apps/tauri-plugin-vibrancy) ![official](https://img.shields.io/badge/-official-FFC131) - Make your Tauri/TAO windows vibrant.\n- [tauri-plugin-shadows](https://github.com/tauri-apps/tauri-plugin-shadows) ![official](https://img.shields.io/badge/-official-FFC131) - Add native shadows to your Tauri/TAO windows.\n- [tauri-plugin-positioner](https://github.com/JonasKruckenberg/tauri-plugin-positioner) - Move windows to common locations.\n \n## Integrations\n\n- [vue-cli-plugin-tauri](https://github.com/tauri-apps/vue-cli-plugin-tauri) ![official](https://img.shields.io/badge/-official-FFC131) - Turn your Vue SPA into a lightweight cross-platform desktop app.\n- [vite-plugin-tauri](https://github.com/amrbashir/vite-plugin-tauri) - Integrate Tauri in a Vite project to build cross-platform apps.\n- [axios-tauri-adapter](https://git.kaki87.net/KaKi87/axios-tauri-adapter) - `axios` adapter for the `@tauri-apps/api/http` module.\n- [svelte-tauri-filedrop](https://github.com/probablykasper/svelte-tauri-filedrop) - File drop handling component for Svelte.\n\n## Apps\n\n### Open Source\n\n- [UsTaxes](https://github.com/ustaxes/ustaxes) - Free, private, open-source US tax filings.\n- [Xplorer](https://github.com/kimlimjustin/xplorer) - Customizable, modern and cross-platform File Explorer.\n- [Clash Verge](https://github.com/zzzgydi/clash-verge) - Rule based proxy for Mac and Windows based on `clash`.\n- [Authme Lite](https://github.com/Levminer/authme-lite) - Two-factor (2FA) authentication app for desktop.\n- [BS Redis Desktop Client](https://github.com/fuyoo/bs-redis-desktop-client) - The Best Surprise Redis Desktop Client.\n- [Kadium](https://github.com/probablykasper/kadium) - App for staying ontop of YouTube channel uploads.\n- [Mr Tagger](https://github.com/probablykasper/mr-tagger) - Music file tagging app.\n- [Time Machine Inspector](https://github.com/probablykasper/time-machine-inspector) - Find out what's taking up your Time Machine backup space.\n- [Identia](https://github.com/iohzrd/identia) - Decentralized social media on IPFS.\n\n### Closed Source\n\n## Tutorials\n\n## Articles\n","url":"https://github.com/tauri-apps/awesome-tauri"}] \ No newline at end of file +[{"id":"github_tauri_apps_tauri","name":"tauri","description":"Build smaller, faster, and more secure desktop applications with a web frontend.","kind":"code","stars":31173,"watchers":31173,"subscribers":314,"openIssues":127,"forks":778,"defaultBranch":"dev","language":"Rust","topics":["hacktoberfest","high-performance","rust","webview","works-with-clojurescript","works-with-construct","works-with-elm","works-with-flutter","works-with-gatsby","works-with-mint","works-with-phaser","works-with-quasar","works-with-react","works-with-reason","works-with-svelte","works-with-vue","works-with-yew"],"isTemplate":false,"lastUpdated":"2022-02-14T20:12:06Z","createdAt":"2019-07-13T09:09:37Z","license":"Other","text":"\"Tauri\"\n\n[![status](https://img.shields.io/badge/Status-Beta-green.svg)](https://github.com/tauri-apps/tauri/tree/dev)\n[![License](https://img.shields.io/badge/License-MIT%20or%20Apache%202-green.svg)](https://opencollective.com/tauri)\n[![test library](https://img.shields.io/github/workflow/status/tauri-apps/tauri/test%20library?label=test%20library)](https://github.com/tauri-apps/tauri/actions?query=workflow%3A%22test+library%22)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)\n\n[![Chat Server](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/SpmNs4S)\n[![devto](https://img.shields.io/badge/blog-dev.to-black.svg)](https://dev.to/tauri)\n[![devto](https://img.shields.io/badge/documentation-tauri.studio-purple.svg)](https://tauri.studio/docs/get-started/intro)\n[![https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg](https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg)](https://good-labs.github.io/greater-good-affirmation)\n[![support](https://img.shields.io/badge/sponsor-open%20collective-blue.svg)](https://opencollective.com/tauri)\n\n## Current Releases\n\n| Component | Description | Version | Lin | Win | Mac |\n| --------------------------------------------------------------------------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | --- | --- | --- |\n| [**cli.rs**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) | create, develop and build apps | [![](https://img.shields.io/crates/v/tauri-cli.svg)](https://crates.io/crates/tauri-cli) | ✅ | ✅ | ✅ |\n| [**cli.js**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli/node) | Node.js CLI wrapper for cli.rs | [![](https://img.shields.io/npm/v/@tauri-apps/cli.svg)](https://www.npmjs.com/package/@tauri-apps/cli) | ✅ | ✅ | ✅ |\n| [**api.js**](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) | JS API for interaction with Rust backend | [![](https://img.shields.io/npm/v/@tauri-apps/api.svg)](https://www.npmjs.com/package/@tauri-apps/api) | ✅ | ✅ | ✅ |\n| [**create-tauri-app**](https://github.com/tauri-apps/tauri/tree/dev/tooling/create-tauri-app) | Get started with your first Tauri app | [![](https://img.shields.io/npm/v/create-tauri-app.svg)](https://www.npmjs.com/package/create-tauri-app) | ✅ | ✅ | ✅ |\n| [**vue-cli-plugin-tauri**](https://github.com/tauri-apps/vue-cli-plugin-tauri/) | Vue CLI plugin for Tauri | [![](https://img.shields.io/npm/v/vue-cli-plugin-tauri.svg)](https://www.npmjs.com/package/vue-cli-plugin-tauri) | ✅ | ✅ | ✅ |\n| [**core**](https://github.com/tauri-apps/tauri/tree/dev/core/tauri) | runtime core | [![](https://img.shields.io/crates/v/tauri.svg)](https://crates.io/crates/tauri) | ✅ | ✅ | ✅ |\n| [**bundler**](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler) | manufacture the final binaries | [![](https://img.shields.io/crates/v/tauri-bundler.svg)](https://crates.io/crates/tauri-bundler) | ✅ | ✅ | ✅ |\n\n## Introduction\nTauri is a framework for building tiny, blazing fast binaries for all major desktop platforms. Developers can integrate any front-end framework that compiles to HTML, JS and CSS for building their user interface. The backend of the application is a rust-sourced binary with an API that the front-end can interact with.\n\nThe user interface in Tauri apps currently leverages [`tao`](https://docs.rs/tao) as a window handling library on macOS and Windows, and [`gtk`](https://gtk-rs.org/docs/gtk/) on Linux via the **Tauri-team** incubated and maintained [WRY](https://github.com/tauri-apps/wry), which creates a unified interface to the system webview (and other goodies like Menu and Taskbar), leveraging WebKit on macOS, WebView2 on Windows and WebKitGTK on Linux.\n\nTo learn more about the details of how all of these pieces fit together, please consult this [ARCHITECTURE.md](https://github.com/tauri-apps/tauri/blob/dev/ARCHITECTURE.md) document.\n\n## Get Started\nIf you are interested in making a tauri-app, please visit the [documentation website](https://tauri.studio). This README is directed towards those who are interested in contributing to the core library. But if you just want a quick overview about where `tauri` is at in its development, here's a quick burndown:\n\n### Platforms\n- [x] Windows 7,8,10\n- [x] Linux\n- [x] macOS\n- [ ] iOS (in progress)\n- [ ] android (soon)\n\n### App Bundles\n- [x] App Icons\n- [x] Build on MacOS (.app, .dmg)\n- [x] Build on Linux (.deb, AppImage)\n- [x] Build on Windows (.exe, .msi)\n- [x] Copy Buffer\n- [x] Device Notifications (toast)\n- [x] Self Updater\n- [x] App Signing\n- [x] Frameless Mode\n- [x] Transparent Mode\n- [x] Multiwindow Mode\n- [x] Tray\n- [ ] deeplink RPC (in progress)\n- [ ] One-Time commands (coming soon)\n\n### Security Features\n- [x] localhost-free (:fire:)\n- [x] custom protocol for secure mode\n- [x] Dynamic ahead of Time Compilation (dAoT) with functional tree-shaking\n- [x] functional Address Space Layout Randomization\n- [x] OTP salting of function names and messages at runtime\n- [x] CSP Injection\n\n### Utilities\n- [x] GH Action for creating binaries for all platforms\n- [x] VS Code Extension\n- [x] Tauri Core Plugins\n- [x] Update core dependencies automatically from the command line\n- [x] Rust-based CLI\n\n### Comparison between Tauri and Electron\n\n| Detail | Tauri | Electron |\n| -------------------------- | ------ | -------------------- |\n| Installer Size Linux | 3.1 MB | 52.1 MB |\n| Memory Consumption Linux | 180 MB | 462 MB |\n| Launch Time Linux | 0.39s | 0.80s |\n| Interface Service Provider | WRY | Chromium |\n| Backend Binding | Rust | Node.js (ECMAScript) |\n| Underlying Engine | Rust | V8 (C/C++) |\n| FLOSS | Yes | No |\n| Multithreading | Yes | Yes |\n| Bytecode Delivery | Yes | No |\n| Multiple Windows | Yes | Yes |\n| Auto Updater | Yes | Yes1 |\n| Custom App Icon | Yes | Yes |\n| Windows Binary | Yes | Yes |\n| MacOS Binary | Yes | Yes |\n| Linux Binary | Yes | Yes |\n| iOS Binary | Soon | No |\n| Android Binary | Soon | No |\n| Desktop Tray | Yes | Yes |\n| Sidecar Binaries | Yes | No |\n\n#### Notes\n1. Electron has no native auto updater on Linux, but is offered by electron-packager\n\n## Development\n\nTauri is a system composed of a number of moving pieces:\n\n### Infrastructure\n- Git for code management\n- GitHub for project management\n- GitHub actions for CI and CD\n- Discord for discussions\n- Netlify-hosted documentation website\n- DigitalOcean meilisearch instance\n\n### Major Runtimes\n- Node.js for running the CLI (deno and pure rust are on the roadmap)\n- Cargo for testing, running the dev service, building binaries and as the runtime harness for the webview\n\n### Major Languages\n- Rust for the CLI\n- EcmaScript bindings to the Rust API, written in typescript\n- Rust for bindings, rust side of the API, harnesses\n- Rust plugins to Tauri backend\n\n### Operating systems\nTauri core can be developed on Mac, Linux and Windows, but you are encouraged to use the latest possible operating systems and build tools for your OS.\n\n### Contributing\nBefore you start working on something, it's best to check if there is an existing issue first. It's also is a good idea to stop by the Discord server and confirm with the team if it makes sense or if someone is already working on it.\n\nPlease make sure to read the [Contributing Guide](./.github/CONTRIBUTING.md) before making a pull request.\n\nThank you to everyone contributing to Tauri!\n\n### Documentation\nDocumentation in a polyglot system is a tricky proposition. To this end, we prefer to use inline documentation of Rust code and at JSDoc in typescript / javascript code. We autocollect these and publish them using Docusaurus v2 and netlify. Here is the hosting repository for the documentation site: https://github.com/tauri-apps/tauri-docs\n\n### Testing & Linting\nTest all the things! We have a number of test suites, but are always looking to improve our coverage:\n- Rust (`cargo test`) => sourced via inline `#[cfg(test)]` declarations\n- TS (`jest`) => via spec files\n- Smoke Tests (run on merges to latest)\n- eslint, clippy\n\n### CI/CD\nWe recommend you read this article to understand better how we run our pipelines: https://www.jacobbolda.com/setting-up-ci-and-cd-for-tauri/\n\n## Organization\nTauri aims to be a sustainable collective based on principles that guide [sustainable free and open software communities](https://sfosc.org). To this end it has become a Programme within the [Commons Conservancy](https://commonsconservancy.org/), and you can contribute financially via [Open Collective](https://opencollective.com/tauri).\n\n## Semver\n**tauri** is following [Semantic Versioning 2.0](https://semver.org/).\n\n## Licenses\nCode: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy.\n\nMIT or MIT/Apache 2.0 where applicable.\n\nLogo: CC-BY-NC-ND\n- Original Tauri Logo Designs by [Alve Larsson](https://alve.io/), [Daniel Thompson-Yvetot](https://github.com/nothingismagick) and [Guillaume Chau](https://github.com/akryum)\n\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_large)\n","url":"https://github.com/tauri-apps/tauri"},{"id":"github_tauri_apps_wry","name":"wry","description":"Cross-platform WebView library in Rust for Tauri.","kind":"code","stars":961,"watchers":961,"subscribers":25,"openIssues":42,"forks":64,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-14T19:47:57Z","createdAt":"2020-07-12T15:12:44Z","license":"Other","text":"\"WRY\n\n[![](https://img.shields.io/crates/v/wry?style=flat-square)](https://crates.io/crates/wry) [![](https://img.shields.io/docsrs/wry?style=flat-square)](https://docs.rs/wry/) ![](https://img.shields.io/crates/l/wry?style=flat-square)\n\nCross-platform WebView rendering library in Rust that supports all major desktop platforms like Windows, macOS, and Linux.\n\n
\n \n \n \n
\n\n## Overview\n\nWry connects the web engine on each platform and provides easy to use and unified interface to render WebView. It also re-exports [tao] as a module for event loop and window creation.\n\n[tao]: https://crates.io/crates/tao\n\n## Usage\n\nThe minimum example to create a Window and browse a website looks like following:\n\n```rust\nfn main() -> wry::Result<()> {\n use wry::{\n application::{\n event::{Event, StartCause, WindowEvent},\n event_loop::{ControlFlow, EventLoop},\n window::WindowBuilder,\n },\n webview::WebViewBuilder,\n };\n\n let event_loop = EventLoop::new();\n let window = WindowBuilder::new()\n .with_title(\"Hello World\")\n .build(&event_loop)?;\n let _webview = WebViewBuilder::new(window)?\n .with_url(\"https://tauri.studio\")?\n .build()?;\n\n event_loop.run(move |event, _, control_flow| {\n *control_flow = ControlFlow::Wait;\n\n match event {\n Event::NewEvents(StartCause::Init) => println!(\"Wry has started!\"),\n Event::WindowEvent {\n event: WindowEvent::CloseRequested,\n ..\n } => *control_flow = ControlFlow::Exit,\n _ => (),\n }\n });\n}\n```\n\nThere are also more samples under `examples`, you can enter commands like following to try them:\n\n```\ncargo run --example multi_window\n```\n\nFor more information, please read the documentation below.\n\n## [Documentation](https://docs.rs/wry)\n\n## Platform-specific notes\n\nAll platforms uses [tao](https://github.com/tauri-apps/tao) to build the window, and wry re-export it as application module. Here are the underlying web engine each platform uses, and some dependencies you might need to install.\n\n### Linux\n\nTao uses [gtk-rs](https://gtk-rs.org/) and its related libraries for window creation and wry also needs [WebKitGTK](https://webkitgtk.org/) for WebView. So please make sure following packages are installed:\n\n#### Arch Linux / Manjaro:\n\n```bash\nsudo pacman -S webkit2gtk libappindicator-gtk3\n```\n\n#### Debian / Ubuntu:\n\n```bash\nsudo apt install libwebkit2gtk-4.0-dev libappindicator3-dev\n```\n\n#### Fedora\n\n```bash\nsudo dnf install gtk3-devel webkit2gtk3-devel libappindicator-gtk3-devel\n```\n\n### macOS\n\nWebKit is native on macOS so everything should be fine.\n\nIf you are cross-compiling for macOS using [osxcross](https://github.com/tpoechtrager/osxcross) and encounter a runtime panic like `Class with name WKWebViewConfiguration could not be found` it's possible that `WebKit.framework` has not been linked correctly, to fix this set the `RUSTFLAGS` environment variable:\n\n```\nRUSTFLAGS=\"-l framework=WebKit\" cargo build --target=x86_64-apple-darwin --release\n```\n\n### Windows\n\nWebView2 provided by Microsoft Edge Chromium is used. So wry supports Windows 7, 8, and 10.\n\n## License\nApache-2.0/MIT\n","url":"https://github.com/tauri-apps/wry"},{"id":"github_tauri_apps_tao","name":"tao","description":"The TAO of cross-platform windowing. A library in Rust built for Tauri.","kind":"code","stars":208,"watchers":208,"subscribers":13,"openIssues":54,"forks":22,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-14T16:20:54Z","createdAt":"2021-05-03T02:40:47Z","license":"Apache License 2.0","text":"\"TAO\n\n[![](https://img.shields.io/crates/v/tao?style=flat-square)](https://crates.io/crates/tao) [![](https://img.shields.io/docsrs/tao?style=flat-square)](https://docs.rs/tao/) ![](https://img.shields.io/crates/l/tao?style=flat-square)\n\n[![Chat Server](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/SpmNs4S)\n[![devto](https://img.shields.io/badge/blog-dev.to-black.svg)](https://dev.to/tauri)\n[![devto](https://img.shields.io/badge/documentation-tauri.studio-purple.svg)](https://tauri.studio/docs/getting-started/intro)\n[![https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg](https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg)](https://good-labs.github.io/greater-good-affirmation)\n[![support](https://img.shields.io/badge/sponsor-open%20collective-blue.svg)](https://opencollective.com/tauri)\n\n\nCross-platform application window creation library in Rust that supports all major platforms like \nWindows, macOS, Linux, iOS and Android. Built for you, maintained for Tauri.\n\n### Cargo Features\n\nTao provides the following features, which can be enabled in your `Cargo.toml` file:\n* `serde`: Enables serialization/deserialization of certain types with [Serde](https://crates.io/crates/serde).\n* `tray`: Enables system tray and more menu item variants on **Linux**. This flag is enabled by default.\n You can still create those types if you disable it. They just don't create the actual objects. We set this flag because some implementations require more installed packages. Disable this if you don't want to install `libappindicator` package.\n* `ayatana`: Enable this if you wish to use more update `libayatana-appindicator` since `libappindicator` is no longer\n maintained.\n\n## Platform-specific notes\n\n### Android\n\nThis library makes use of the [ndk-rs](https://github.com/rust-windowing/android-ndk-rs) crates, refer to that repo for more documentation.\n\nRunning on an Android device needs a dynamic system library, add this to Cargo.toml:\n```toml\n[[example]]\nname = \"request_redraw_threaded\"\ncrate-type = [\"cdylib\"]\n```\n\nAnd add this to the example file to add the native activity glue:\n\n```rust\n#[cfg_attr(target_os = \"android\", ndk_glue::main(backtrace = \"on\"))]\nfn main() {\n ...\n}\n```\n\nAnd run the application with `cargo apk run --example request_redraw_threaded`\n\n### Linux\n\nGtk and its related libraries are used to build the support of Linux. Be sure to install following packages before building:\n\n#### Arch Linux / Manjaro:\n\n```bash\nsudo pacman -S gtk3 libappindicator-gtk3\n```\n\n#### Debian / Ubuntu:\n\n```bash\nsudo apt install libgtk-3-dev libappindicator3-dev\n```\n\n#### MacOS\n\nTo ensure compatibility with older MacOS systems, tao links to\nCGDisplayCreateUUIDFromDisplayID through the CoreGraphics framework.\nHowever, under certain setups this function is only available to be linked\nthrough the newer ColorSync framework. So, tao provides the\n`TAO_LINK_COLORSYNC` environment variable which can be set to `1` or `true`\nwhile compiling to enable linking via ColorSync.\n\n### Acknowledgement\n\nWe would like to thank the authors and contributors to [winit](https://crates.io/crates/winit)\nfor their groundbreaking work upon which this crate is not only based, but\nalso leans heavily upon. Thankyou!!!\n","url":"https://github.com/tauri-apps/tao"},{"id":"github_tauri_apps_tauri_action","name":"tauri-action","description":"Build your Web application as a Tauri binary for MacOS, Linux and Windows","kind":"unknown","stars":102,"watchers":102,"subscribers":10,"openIssues":21,"forks":23,"defaultBranch":"dev","language":"TypeScript","topics":["github-actions","hacktoberfest"],"isTemplate":false,"lastUpdated":"2022-02-01T20:21:04Z","createdAt":"2020-07-07T21:41:23Z","license":"MIT License","text":"# Tauri GitHub Action\n\nThis GitHub Action builds your Web application as a Tauri native binary for MacOS, Linux and Windows.\nIf your project doesn't include the Tauri files, we create it at compile time, so if you don't need to use Tauri's API, you can just ship native apps through this Action.\n\n# Usage\n\nThis GitHub Action has three main usages: test the build pipeline of your Tauri app, uploading Tauri artifacts to an existing release, and creating a new release with the Tauri artifacts.\n\n## Testing the Build\n\n```yml\nname: \"test-on-pr\"\non: [pull_request]\n\njobs:\n test-tauri:\n strategy:\n fail-fast: false\n matrix:\n platform: [macos-latest, ubuntu-latest, windows-latest]\n\n runs-on: ${{ matrix.platform }}\n steps:\n - uses: actions/checkout@v2\n - name: setup node\n uses: actions/setup-node@v1\n with:\n node-version: 12\n - name: install Rust stable\n uses: actions-rs/toolchain@v1\n with:\n toolchain: stable\n - name: install webkit2gtk (ubuntu only)\n if: matrix.platform == 'ubuntu-latest'\n run: |\n sudo apt-get update\n sudo apt-get install -y webkit2gtk-4.0\n - name: install app dependencies and build it\n run: yarn && yarn build\n - uses: tauri-apps/tauri-action@v0\n env:\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\n## Creating a release and uploading the Tauri bundles\n\n```yml\nname: \"publish\"\non:\n push:\n branches:\n - release\n\njobs:\n publish-tauri:\n strategy:\n fail-fast: false\n matrix:\n platform: [macos-latest, ubuntu-latest, windows-latest]\n\n runs-on: ${{ matrix.platform }}\n steps:\n - uses: actions/checkout@v2\n - name: setup node\n uses: actions/setup-node@v1\n with:\n node-version: 12\n - name: install Rust stable\n uses: actions-rs/toolchain@v1\n with:\n toolchain: stable\n - name: install webkit2gtk (ubuntu only)\n if: matrix.platform == 'ubuntu-latest'\n run: |\n sudo apt-get update\n sudo apt-get install -y webkit2gtk-4.0\n - name: install app dependencies and build it\n run: yarn && yarn build\n - uses: tauri-apps/tauri-action@v0\n env:\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n with:\n tagName: app-v__VERSION__ # the action automatically replaces \\_\\_VERSION\\_\\_ with the app version\n releaseName: \"App v__VERSION__\"\n releaseBody: \"See the assets to download this version and install.\"\n releaseDraft: true\n prerelease: false\n```\n\n## Uploading the artifacts to a release\n\nNote that `actions/create-release` isn't maintained so you should find an alternative or let the Tauri Action handle the release.\n\n```yml\nname: \"test-on-pr\"\non: [pull_request]\n\njobs:\n create-release:\n runs-on: ubuntu-latest\n outputs:\n RELEASE_UPLOAD_ID: ${{ steps.create_release.outputs.id }}\n\n steps:\n - uses: actions/checkout@v2\n - name: setup node\n uses: actions/setup-node@v1\n with:\n node-version: 12\n - name: get version\n run: echo \"PACKAGE_VERSION=$(node -p \"require('./package.json').version\")\" >> $GITHUB_ENV\n - name: create release\n id: create_release\n uses: actions/create-release@v1.1.0\n env:\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n with:\n tag_name: app-v${{ env.PACKAGE_VERSION }}\n release_name: \"Desktop app v${{ env.PACKAGE_VERSION }}\"\n body: \"See the assets to download this version and install.\"\n draft: true\n prerelease: false\n build-tauri:\n needs: create-release\n strategy:\n fail-fast: false\n matrix:\n platform: [macos-latest, ubuntu-latest, windows-latest]\n\n runs-on: ${{ matrix.platform }}\n steps:\n - uses: actions/checkout@v2\n - name: setup node\n uses: actions/setup-node@v1\n with:\n node-version: 12\n - name: install Rust stable\n uses: actions-rs/toolchain@v1\n with:\n toolchain: stable\n - name: install webkit2gtk (ubuntu only)\n if: matrix.platform == 'ubuntu-latest'\n run: |\n sudo apt-get update\n sudo apt-get install -y webkit2gtk-4.0\n - name: install app dependencies and build it\n run: yarn && yarn build\n - uses: tauri-apps/tauri-action@v0\n env:\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n with:\n releaseId: ${{ needs.create-release.outputs.RELEASE_UPLOAD_ID }}\n```\n\n## Inputs\n\n| Name | Required | Description | Type | Default |\n| ------------------ | :------: | ------------------------------------------------------------------------------------------- | ------ | --------------------- |\n| `projectPath` | false | Path to the root of the project that will be built | string | . |\n| `configPath` | false | Path to the tauri.conf.json file if you want a configuration different from the default one | string | tauri.conf.json |\n| `distPath` | false | Path to the distributable folder with your index.html and JS/CSS | string | |\n| `releaseId` | false | The id of the release to upload artifacts as release assets | string | |\n| `tagName` | false | The tag name of the release to create | string | |\n| `releaseName` | false | The name of the release to create | string | |\n| `releaseBody` | false | The body of the release to create | string | |\n| `releaseDraft` | false | Whether the release to create is a draft or not | bool | false |\n| `prerelease` | false | Whether the release to create is a prerelease or not | bool | false |\n| `releaseCommitish` | false | Any branch or commit SHA the Git tag is created from, unused if the Git tag already exists | string | SHA of current commit |\n| `iconPath` | false | path to the PNG icon to use as app icon, relative to the projectPath | string | |\n| `includeDebug` | false | whether to include a debug build or not | bool | |\n| `tauriScript` | false | the script to execute the Tauri CLI | string | `yarn\\|npm tauri` |\n\n## Outputs\n\n| Name | Description |\n| ------------------ | ------------------------------------------------------------------ |\n| `releaseId` | The ID of the created release |\n| `releaseHtmlUrl` | The URL users can navigate to in order to view the created release |\n| `releaseUploadUrl` | The URL for uploading assets to the created release |\n\n# Caveats\n\n- You can use this Action on a repo that doesn't have Tauri configured. We automatically initialize Tauri before building, and configure it to use your Web artifacts.\n - You can configure Tauri with the `configPath`, `distPath` and `iconPath` options.\n- You can run custom Tauri CLI scripts with the `tauriScript` option. So instead of running `yarn tauri build` or `npx tauri build`, we'll execute `${tauriScript}`.\n - Useful when you need custom build functionality when creating Tauri apps e.g. a `desktop:build` script.\n- When your app isn't on the root of the repo, use the `projectPath` input.\n","url":"https://github.com/tauri-apps/tauri-action"},{"id":"github_tauri_apps_tauri_docs","name":"tauri-docs","description":"The source for all tauri project documentation.","kind":"documentation","stars":223,"watchers":223,"subscribers":17,"openIssues":65,"forks":88,"defaultBranch":"dev","language":"JavaScript","topics":["documentation","hacktoberfest","tauri"],"isTemplate":false,"lastUpdated":"2022-02-14T11:26:00Z","createdAt":"2020-03-09T00:22:43Z","license":"MIT License","text":"# Tauri Docs\n\nThis website is built using [Docusaurus 2](https://v2.docusaurus.io/) with [MeiliSearch](https://github.com/meilisearch/) for the docs indexation and is deployed by Netlify.\n\n[![Deploys By Netlify](https://www.netlify.com/img/global/badges/netlify-light.svg)](https://www.netlify.com)\n\nIf you seek to change something from **our guides**, please refer to [the docs folder](https://github.com/tauri-apps/tauri-docs/tree/dev/docs). \\\nWhen browsing the website, you will find edit links at the bottom of these docs.\n\nThe **API docs** are generated from our [Rust](https://github.com/tauri-apps/tauri/tree/dev/core/tauri) and [TypeScript](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) source code.\n\n## Installation\n\n```\n$ yarn\n```\n\n## Local Development\n\n```\n$ yarn start\n```\n\nThis command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server.\n\nTo develop in another language, use this command (setting your desired language):\n```\n$ yarn start --locale fr\n```\n\n## Build\n\n```\n$ yarn build\n```\n\nThis command generates static content and can be served using any static contents hosting service.\n\nTo build for only a specific language use:\n\n```\nyarn build --locale fr\n```\n\n## Deployment\n\n```\n$ GIT_USER= USE_SSH=true yarn deploy\n```\n\nIf you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.\n\n## Contributing\n\n### Writing/fixing docs\n\nFeel free to open an issue/a PR if you find something weird in the docs.\n\nYour PR once submitted to us, will automatically deploy to a temporary Netlify instance for us or you to review through GitHub's CI/CD checks: you will be able to click on a preview link once the build is ready.\n\n### Internationalization (i18n)\n\nWe're working with Crowdin to manage translations, if you feel like you want to lend a hand for translations, take a look at the documentation project: https://tauri.crowdin.com/documentation\n\nTo add a language to the site, add it to `docusaurus.config.js`'s `siteconfig.i18n.locales` object.\n\nThe following items should be translated before enabling a language:\n\n- strings in i18n/[language] json files\n- docs/about/intro.md and docs/about/security.md;\n- all files in docs/getting-started;\n- all files in docs/development;\n\n\n\n## License\n\nMIT License\n\nCopyright (c) 2020-2021 Tauri Programme within The Commons Conservancy\n","url":"https://github.com/tauri-apps/tauri-docs"},{"id":"github_tauri_apps_tauri_vscode","name":"tauri-vscode","description":"Visual Studio Code Extension for Tauri apps development","kind":"unknown","stars":47,"watchers":47,"subscribers":9,"openIssues":6,"forks":4,"defaultBranch":"dev","language":"TypeScript","topics":[],"isTemplate":false,"lastUpdated":"2022-02-11T13:02:49Z","createdAt":"2020-07-06T16:20:49Z","text":"# Tauri VS Code Extension\n\nVisual Studio Code Extension that adds support to Tauri commands and `tauri.conf.json` JSON validation.\n\n## Supported commands\n\nIt adds the `init`, `deps`, `dev` and `build` commands to the `Command Palette`.\n\n## JSON validation\n\nThe extension automatically pulls the [latest config schema](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli/schema.json) so VS Code can display documentation and autocomplete.\n\n# Contributing\n\nFollowing [the official guide](https://code.visualstudio.com/api/get-started/your-first-extension), run `yarn` to install dependencies, `yarn compile` to build your changes and press `F5` to open a new `Extension Development Host` window.\n","url":"https://github.com/tauri-apps/tauri-vscode"},{"id":"github_tauri_apps_tauri_plugin_upload","name":"tauri-plugin-upload","description":"Tauri plugin for file uploads through HTTP","kind":"plugin","stars":2,"watchers":2,"subscribers":8,"openIssues":3,"forks":1,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2021-12-15T22:05:39Z","createdAt":"2021-10-01T16:11:09Z","license":"Other","text":"# Tauri Plugin Upload\n![Test](https://github.com/tauri-apps/tauri-plugin-upload/workflows/Test/badge.svg)\n\nThis plugin provides an interface for file uploads.\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition.\n\n### `/webview-src`\nTypescript source for the /webview-dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a Tauri application.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the example app](examples/svelte-app). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-upload]\ngit = \"https://github.com/tauri-apps/tauri-plugin-upload\"\ntag = \"v0.1.0\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_upload::Upload;\n\nfn main() {\n tauri::Builder::default()\n .plugin(Upload::default())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-upload#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-upload#v0.1.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-upload#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n# or\nyarn add github:tauri-apps/tauri-plugin-upload#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-upload-api\": \"github:tauri-apps/tauri-plugin-upload#v0.1.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport upload from 'tauri-plugin-upload-api'\nawait upload('/path/to/file')\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-upload"},{"id":"github_tauri_apps_tauri_plugin_window_state","name":"tauri-plugin-window-state","description":null,"kind":"plugin","stars":6,"watchers":6,"subscribers":8,"openIssues":4,"forks":0,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-12T17:35:59Z","createdAt":"2021-09-26T04:49:19Z","license":"Other","text":"# Tauri Plugin Window State\n![Test](https://github.com/tauri-apps/tauri-plugin-window-state/workflows/Test/badge.svg)\n\nThis plugin provides a Tauri Plugin that saves the window position and size and restores it when the app is reopened.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the vanilla demo](examples/vanilla/src-tauri/src/main.rs).\nPlease note, below in the dependencies you can also lock to a revision/tag in the `Cargo.toml`.\n\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri]\ngit = \"https://github.com/tauri-apps/tauri/\"\nbranch = \"next\"\nfeatures = [\"api-all\"]\n\n[dependencies.tauri-plugin-window-state]\ngit = \"https://github.com/tauri-apps/tauri-plugin-window-state\"\ntag = \"tauri-plugin-window-state-v0.1.0\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nfn main() {\n tauri::Builder::default()\n .plugin(tauri_plugin_window_state::WindowState::default())\n .run();\n}\n```\n\nTo prevent flashes when the window is updated, the window `visible` property must be set to `false`.\nThe plugin is responsible for showing it after restoring its state.\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-window-state"},{"id":"github_tauri_apps_tauri_plugin_store","name":"tauri-plugin-store","description":"This plugin provides an interface for storing unencrypted values on the application cache folder.","kind":"plugin","stars":16,"watchers":16,"subscribers":8,"openIssues":2,"forks":4,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-10T15:05:00Z","createdAt":"2021-09-27T16:10:02Z","license":"Other","text":"# Tauri Plugin Store\n\n[![devto](https://img.shields.io/badge/documentation-github.io-purple.svg)](https://tauri-apps.github.io/tauri-plugin-store)\n![Test](https://github.com/tauri-apps/tauri-plugin-store/workflows/Test/badge.svg)\n\nThis plugin provides an interface for storing unencrypted values on the application cache folder.\n\n## Architecture\n\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\n\nRust source code that contains the plugin definition.\n\n### `/webview-src`\n\nTypescript source for the /webview-dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\n\nTree-shakeable transpiled JS to be consumed in a Tauri application.\n\n### `/bindings`\n\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\n\nThere are three general methods of installation that we can recommend.\n\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the example app](examples/svelte-app). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n\n`src-tauri/Cargo.toml`\n\n```yaml\n[dependencies.tauri-plugin-store]\ngit = \"https://github.com/tauri-apps/tauri-plugin-store\"\ntag = \"v0.1.0\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n\n```rust\nuse tauri_plugin_store::PluginBuilder;\n\nfn main() {\n tauri::Builder::default()\n .plugin(PluginBuilder::default().build())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n\n`Install from a tagged release`\n\n```\nnpm install github:tauri-apps/tauri-plugin-store#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-store#v0.1.0\n```\n\n`Install from a commit`\n\n```\nnpm install github:tauri-apps/tauri-plugin-store#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n# or\nyarn add github:tauri-apps/tauri-plugin-store#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n```\n\n`package.json`\n\n```json\n \"dependencies\": {\n \"tauri-plugin-store-api\": \"github:tauri-apps/tauri-plugin-store#v0.1.0\",\n```\n\nUse within your JS/TS:\n\n```ts\nimport { Store } from 'tauri-plugin-store-api';\nconst store = new Store('.settings.dat');\nawait store.set('some-key', { value: 5 });\nconst val = await store.get('some-key');\nassert(val, { value: 5 });\n```\n\n# License\n\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-store"},{"id":"github_tauri_apps_tauri_plugin_websocket","name":"tauri-plugin-websocket","description":null,"kind":"plugin","stars":5,"watchers":5,"subscribers":8,"openIssues":4,"forks":0,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-01-30T04:52:31Z","createdAt":"2021-09-14T23:49:58Z","text":"","url":"https://github.com/tauri-apps/tauri-plugin-websocket"},{"id":"github_tauri_apps_tauri_plugin_fs_extra","name":"tauri-plugin-fs-extra","description":"Tauri plugin that adds file system methods that aren't included in the core API","kind":"plugin","stars":5,"watchers":5,"subscribers":8,"openIssues":2,"forks":0,"defaultBranch":"dev","language":"TypeScript","topics":[],"isTemplate":false,"lastUpdated":"2022-02-13T16:18:05Z","createdAt":"2021-10-19T15:18:57Z","license":"Other","text":"# tauri-plugin-fs-extra\n![Test](https://github.com/tauri-apps/tauri-plugin-fs-extra/workflows/Test/badge.svg)\n\nThis plugin provides a \"classical\" Tauri Plugin Interface that adds file system methods that aren't included in the Tauri core API.\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition.\n\n### `/webview-src`\nTypescript source for the /webview-dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a Tauri application.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the Todo app](examples/todos-app/). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-fs-extra]\ngit = \"https://github.com/tauri-apps/tauri-plugin-fs-extra\"\ntag = \"v0.1.0\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_fs_extra::FsExtra;\n\nfn main() {\n tauri::Builder::default()\n .plugin(FsExtra::default())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-fs-extra#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-fs-extra#v0.1.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-fs-extra#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n# or\nyarn add github:tauri-apps/tauri-plugin-fs-extra#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-fs-extra-api\": \"github:tauri-apps/tauri-plugin-fs-extra#v0.1.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport { metadata } from 'tauri-plugin-fs-extra-api'\nawait metadata('/path/to/file')\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-fs-extra"},{"id":"github_tauri_apps_tauri_plugin_stronghold","name":"tauri-plugin-stronghold","description":"An official Tauri Plugin for using Stronghold.","kind":"plugin","stars":21,"watchers":21,"subscribers":7,"openIssues":24,"forks":2,"defaultBranch":"main","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-06T02:23:36Z","createdAt":"2021-02-15T12:52:23Z","license":"Other","text":"# Tauri Plugin Stronghold\n![Test](https://github.com/tauri-apps/tauri-plugin-stronghold/workflows/Test/badge.svg)\n\nThis plugin provides a \"classical\" Tauri Plugin Interface to the [IOTA Stronghold](https://github.com/iotaledger/stronghold.rs) encrypted database, secure runtime, and peer-to-peer service.\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition and Stronghold features.\n\n### `/webview-src`\nTypescript source for the /dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a WRY webview.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the svelte demo](examples/svelte-app/src/App.svelte). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-stronghold]\ngit = \"https://github.com/tauri-apps/tauri-plugin-stronghold\"\ntag = \"v0.1.0\"\n#branch = \"main\"\n\n# temporary fix to version resolution\n[patch.crates-io]\naesni = { git = \"https://github.com/RustCrypto/block-ciphers/\", rev = \"268dadc93df08928de3bc510ddf20aabfcc49435\" }\naes-soft = { git = \"https://github.com/RustCrypto/block-ciphers/\", rev = \"268dadc93df08928de3bc510ddf20aabfcc49435\" }\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_stronghold::TauriStronghold;\n\nfn main() {\n tauri::Builder::default()\n .plugin(TauriStronghold {})\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-stronghold#v0.2.0\n# or\nyarn add github:tauri-apps/tauri-plugin-stronghold#v0.2.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-stronghold#6749525a47a95439c9703d3a49b94ac65660998f\n# or\nyarn add github:tauri-apps/tauri-plugin-stronghold#6749525a47a95439c9703d3a49b94ac65660998f\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-stronghold-api\": \"github:tauri-apps/tauri-plugin-stronghold#v0.2.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport { Stronghold, Location } from 'tauri-plugin-stronghold-api'\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-stronghold"},{"id":"github_tauri_apps_tauri_plugin_log","name":"tauri-plugin-log","description":null,"kind":"plugin","stars":9,"watchers":9,"subscribers":9,"openIssues":4,"forks":1,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-01-10T22:29:42Z","createdAt":"2021-09-14T17:58:12Z","license":"Other","text":"# Tauri Plugin Log\n\nThis plugin provides configurable interfaces for capturing and storing logs.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the example app](examples/svelte-app). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-log]\ngit = \"https://github.com/tauri-apps/tauri-plugin-log\"\ntag = \"v0.1.0\"\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-log#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-log#v0.1.0\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-log-api\": \"tauri-apps/tauri-plugin-log#v0.1.0\",\n```\n\n## Usage\n\n### RUST\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_log::{LogTarget, LoggerBuilder};\nfn main() {\n tauri::Builder::default()\n .plugin(LoggerBuilder::new([\n LogTarget::LogDir,\n LogTarget::Stdout,\n LogTarget::Webview,\n ]).build())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n\n```ts\nimport { trace, info, error, attachConsole } from 'tauri-plugin-log-api'\n\n// with LogTarget::Webview enabled this function will print logs to the browser console\nconst detach = await attachConsole()\n\ntrace(\"Trace\")\ninfo(\"Info\")\nerror(\"Error\")\n\n// detach the browser console from the log stream\ndetach()\n```\n","url":"https://github.com/tauri-apps/tauri-plugin-log"},{"id":"github_tauri_apps_tauri_plugin_sql","name":"tauri-plugin-sql","description":null,"kind":"plugin","stars":33,"watchers":33,"subscribers":9,"openIssues":9,"forks":4,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-13T19:17:04Z","createdAt":"2021-09-13T23:51:17Z","license":"Other","text":"# Tauri Plugin SQL\n![Test](https://github.com/tauri-apps/tauri-plugin-sql/workflows/Test/badge.svg)\n\nThis plugin provides a \"classical\" Tauri Plugin Interface to SQL databases through [sqlx](https://github.com/launchbadge/sqlx).\nIt supports the `sqlite`, `mysql` and `postgres` drivers, enabled through a Cargo feature.\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition and `sqlx` features.\n\n### `/webview-src`\nTypescript source for the /webview-dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a Tauri application.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the Todo app](examples/todos-app/). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-sql]\ngit = \"https://github.com/tauri-apps/tauri-plugin-sql\"\ntag = \"v0.1.0\"\nfeatures = [\"sqlite\"] # or \"postgres\", or \"mysql\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_sql::TauriSql;\n\nfn main() {\n tauri::Builder::default()\n .plugin(TauriSql::default())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-sql#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-sql#v0.1.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-sql#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n# or\nyarn add github:tauri-apps/tauri-plugin-sql#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-sql-api\": \"github:tauri-apps/tauri-plugin-sql#v0.1.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport Database from 'tauri-plugin-sql-api'\n\n// sqlite. The path is relative to `tauri::api::path::BaseDirectory::App`.\nconst db = await Database.load('sqlite:test.db')\n// mysql\nconst db = await Database.load('mysql://user:pass@host/database')\n// postgres\nconst db = await Database.load('postgres://postgres:password@localhost/test')\n\nawait db.execute('INSERT INTO ...')\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-sql"},{"id":"github_tauri_apps_tauri_plugin_shadows","name":"tauri-plugin-shadows","description":"Add native shadows to your Tauri/TAO windows.","kind":"plugin","stars":3,"watchers":3,"subscribers":8,"openIssues":1,"forks":0,"defaultBranch":"dev","language":"Rust","topics":["macos","plugin","shadows","tao","tauri","tauri-plugin","windows"],"isTemplate":false,"lastUpdated":"2022-01-24T06:34:53Z","createdAt":"2021-12-30T14:10:26Z","license":"Other","text":"# tauri-plugin-shadows\n\nAdd native shadows to your Tauri/TAO windows.\n\n## Platform support\n\n - **`Windows:`** Yes, but shadows can't be turned off for a normal (decorated) window.\n - **`macOS:`** Yes!\n - **`Linux:`** No, shadows are controlled by the compositor installed on the user system and they can enable it for your app if they want.\n\n## Installation\n\nAdd it as a dependncy in `Cargo.toml` of your Tao/Tauri project\n```toml\n[dependencies]\ntauri-plugin-shadows = { git = \"https://github.com/tauri-apps/tauri-plugin-shadows\", features = [\"tauri-impl\"] } # or \"tao-impl\" for TAO projects.\n```\n\n## Cargo Features:\n\n- `tauri-impl`: for Tauri projects.\n- `tao-impl`: for TAO projects.\n\n## Usage\nImport the `Shadows` trait and use `set_shadow()` on your window type:\n- Tauri:\n ```rs\n let window = app.get_window(\"main\").unwrap();\n\n use tauri_plugin_shadows::Shadows;\n window.set_shadow(true);\n ```\n- Tao:\n ```rs\n let window = WindowBuilder::new().with_transparent(true).build(&event_loop).unwrap();\n\n use tauri_plugin_shadows::Shadows;\n window.set_shadow(true);\n ```","url":"https://github.com/tauri-apps/tauri-plugin-shadows"},{"id":"github_tauri_apps_tauri_plugin_vibrancy","name":"tauri-plugin-vibrancy","description":"Make your Tauri/TAO windows vibrant.","kind":"plugin","stars":12,"watchers":12,"subscribers":8,"openIssues":3,"forks":3,"defaultBranch":"dev","language":"Rust","topics":["acrylic","blur","macos","plugin","tao","tauri","tuari-plugin","vibrancy","windows"],"isTemplate":false,"lastUpdated":"2022-02-07T17:32:38Z","createdAt":"2021-11-30T17:19:44Z","license":"Other","text":"# tauri-plugin-vibrancy\n\nMake your Tauri/TAO windows vibrant.\n\n## Platform support\n\n- **`Windows:`** Yes!\n- **`macOS:`** Yes!\n- **`Linux:`** No, blur effect is controlled by the compositor installed on the user system and they can enable it for your app if they want.\n\n## Installation\n\nAdd it as a dependncy in `Cargo.toml` of your Tao/Tauri project\n```toml\n[dependencies]\ntauri-plugin-vibrancy = { git = \"https://github.com/tauri-apps/tauri-plugin-vibrancy\", features = [\"tauri-impl\"] } # or \"tao-impl\" for TAO projects.\n```\n\n## Cargo Features:\n\n- `tauri-impl`: for Tauri projects.\n- `tao-impl`: for TAO projects.\n\n## Usage\n\n1. Enable transparency on your window:\n - Tauri: Edit your window in `tauri.conf.json > tauri > windows` and add `\"transparent\": true`\n or use `tauri::WindowBuilder::transparent`.\n - TAO: Use `tao::window::WindowBuilder::with_transparent`.\n2. Use the `Vibrancy` trait methods on your window type:\n - Tauri:\n ```rs\n let window = app.get_window(\"main\").unwrap();\n\n use tauri_plugin_vibrancy::Vibrancy;\n #[cfg(target_os = \"windows\")]\n window.apply_blur();\n #[cfg(target_os = \"macos\")]\n {\n use tauri_plugin_vibrancy::MacOSVibrancy;\n window.apply_vibrancy(MacOSVibrancy::AppearanceBased);\n }\n ```\n - Tao:\n ```rs\n let window = WindowBuilder::new().with_transparent(true).build(&event_loop).unwrap();\n\n use tauri_plugin_vibrancy::Vibrancy;\n #[cfg(target_os = \"windows\")]\n window.apply_blur();\n #[cfg(target_os = \"macos\")]\n {\n use tauri_plugin_vibrancy::MacOSVibrancy;\n window.apply_vibrancy(MacOSVibrancy::AppearanceBased);\n }\n ```\n\n## Available methods\n\n> Please read the methods documentation in [src/lib.rs](src/lib.rs)\n- `apply_blur()` - **`Windows`**\n- `apply_acrylic()` - **`Windows`** works on Windows 10 v1809 and above and has bad performance when resizing/dragging the window\n- `apply_vibrancy()` - **`macOS`** thanks to [@youngsing](https://github.com/youngsing)\n\n## TODOS\n\n- [ ] `apply_mica()` for Windows 11\n\n","url":"https://github.com/tauri-apps/tauri-plugin-vibrancy"},{"id":"github_tauri_apps_tauri_plugin_localhost","name":"tauri-plugin-localhost","description":"An official Tauri Plugin for using a localhost server in production apps.","kind":"plugin","stars":5,"watchers":5,"subscribers":8,"openIssues":4,"forks":1,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-01-08T16:29:22Z","createdAt":"2021-11-13T01:45:52Z","text":"# Tauri Plugin Localhost\n","url":"https://github.com/tauri-apps/tauri-plugin-localhost"},{"id":"github_tauri_apps_tauri_plugin_fs_watch","name":"tauri-plugin-fs-watch","description":"A Tauri Plugin to watch the filesystem for changes","kind":"plugin","stars":7,"watchers":7,"subscribers":8,"openIssues":4,"forks":1,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-01-28T07:36:40Z","createdAt":"2021-10-18T16:16:35Z","text":"# Tauri Plugin FSWatch\n![Test](https://github.com/tauri-apps/tauri-plugin-fs-watch/workflows/Test/badge.svg)\n\nThis plugin provides a \"classical\" Tauri Plugin Interface to watch changes on files and directories through [notify](https://github.com/notify-rs/notify).\n\n## Architecture\nThis repo shape might appear to be strange, but it is really just a hybrid Rust / Typescript project that recommends a specific type of consumption, namely using GIT as the secure distribution mechanism, and referencing specific unforgeable git hashes. Of course, it can also be consumed via Cargo and NPM.\n\n### `/src`\nRust source code that contains the plugin definition.\n\n### `/webview-src`\nTypescript source for the /webview-dist folder that provides an API to interface with the rust code.\n\n### `/webview-dist`\nTree-shakeable transpiled JS to be consumed in a Tauri application.\n\n### `/bindings`\nForthcoming tauri bindings to other programming languages, like DENO.\n\n## Installation\nThere are three general methods of installation that we can recommend.\n1. Pull sources directly from Github using git tags / revision hashes (most secure, good for developement, shown below)\n2. Git submodule install this repo in your tauri project and then use `file` protocol to ingest the source\n3. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked)\n\nFor more details and usage see [the Todo app](examples/todos-app/). Please note, below in the dependencies you can also lock to a revision/tag in both the `Cargo.toml` and `package.json`\n\n### RUST\n`src-tauri/Cargo.toml`\n```yaml\n[dependencies.tauri-plugin-fs-watch]\ngit = \"https://github.com/tauri-apps/tauri-plugin-fs-watch\"\ntag = \"v0.1.0\"\n#branch = \"main\"\n```\n\nUse in `src-tauri/src/main.rs`:\n```rust\nuse tauri_plugin_fs_watch::Watcher;\n\nfn main() {\n tauri::Builder::default()\n .plugin(Watcher::default())\n .build()\n .run();\n}\n```\n\n### WEBVIEW\n`Install from a tagged release`\n```\nnpm install github:tauri-apps/tauri-plugin-fs-watch#v0.1.0\n# or\nyarn add github:tauri-apps/tauri-plugin-fs-watch#v0.1.0\n```\n\n`Install from a commit`\n```\nnpm install github:tauri-apps/tauri-plugin-fs-watch#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n# or\nyarn add github:tauri-apps/tauri-plugin-fs-watch#488558717b77d8a2bcb37acfd2eca9658aeadc8e\n```\n\n`package.json`\n```json\n \"dependencies\": {\n \"tauri-plugin-fs-watch-api\": \"github:tauri-apps/tauri-plugin-fs-watch#v0.1.0\",\n```\n\nUse within your JS/TS:\n```ts\nimport { watch, watchImmediate } from 'tauri-plugin-fs-watch-api'\n\n// can also watch an array of paths\nconst stopWatching = await watch('/path/to/something', { recursive: true }, event => {\n const { type, payload } = event\n})\n\nconst stopRawWatcher = await watchImmediate(['/path/a', '/path/b'], {}, event => {\n const { path, operation, cookie } = event\n})\n```\n\n# License\nMIT / Apache-2.0\n","url":"https://github.com/tauri-apps/tauri-plugin-fs-watch"},{"id":"github_tauri_apps_tauri_forage","name":"tauri-forage","description":"Currified localForage with a side of extras.","kind":"unknown","stars":7,"watchers":7,"subscribers":6,"openIssues":7,"forks":2,"defaultBranch":"dev","language":"TypeScript","topics":[],"isTemplate":false,"lastUpdated":"2022-01-17T06:27:39Z","createdAt":"2020-01-15T11:32:27Z","text":"# tauri forage\n![test library](https://github.com/tauri-apps/tauri-forage/workflows/test%20library/badge.svg?branch=dev)\n![npm version](https://img.shields.io/npm/v/@tauri-apps/tauri-forage.svg)\n\n[localForage](https://localforage.github.io/localForage/) is a great way to make sure that you've got the most persistent localStorage available on the device and webview that you are using, but operations (like replacing a keyValue) can be tedious, and our approach of multi-op currying makes it very flexible. It is written and tested in typescript, and ships with commonjs and an ejs versions - as well as all of its own typings in case you are using typescript.\n\nIf you don't know how localForage works, you would do well to check out those docs - because that is the underlying engine that this library uses. But for a refresher, localForage uses IndexedDB, WebSQL, or localStorage - depending on the best engine that the browser offers.\n\n## Installation\n\nInstall with your package manager\n```\nyarn add @tauri-apps/tauri-forage\n```\n\nImport into your JS / TS\n```\nimport { forage } from '@tauri-apps/tauri-forage'\n```\n\nUse it:\n```\nforage.setItem({\n key: 'yourKey',\n value: 'a value'\n})()\n```\n\n## How does it work?\nHere is the `getItem` function. There is a lot to discuss, and once you've understood the principle all of the other functions will make sense to you. If you want to see more details, check out the tests in `test/__tests__/tauriForage.spec.ts`\n\n```ts\ngetItem ({ key, logger, returner, before, store }: BeforeItem = {}) {\n return async function (curry?: MaybeFunction) {\n const storage = await _defineStore({ store: store })\n key = before ? await handler.maybeCurry(curry || null)(key) : key\n return handler.returner(\n storage.getItem(key).then(async (v: any) => {\n return !before ? handler.maybeCurry(curry || null)(v) : v\n }).catch((err: any) => {\n /* istanbul ignore next */\n return handler.logger(err, logger)\n })\n )(returner)\n }\n}\n```\n\nIn its most simple incarnation, you can just get the keyValue of the keyName.\n```\n```\n\n### Returner\nYou can instruct every function to return the value in specific ways.\n\n#### TYPES\n- 1(quiet) - return void 0\n- 2(console) - log the returned value to the console\n- 3(break) - throw an error with the contents of the return\n- 4(truthy) - return a true or false value\n- 5(typeof) - return type of response\n- 6(trace) - get a console.trace() of the call stack\n- 7(passthrough) - the default does nothing to the return\n\n\n### Logger\nIf an error occurs, you can determine how to respond:\n\n#### TYPES\n- 1(none) - just return\n- 2(string) - returned the string value of the error\n- 3(trace) - try to return a stack trace up to the error\n- 4(console) - write a console.error\n- 5(throw) - throw the error\n- 6(default) - return undefined\n\n> If you want, you can also use these handler functions yourself! They are properly exported and typed!\n\n### Currying\nHowever you can also curry the returned value with a function you can pass into the function call.\n\nLet's look at a few tests to see how currying can be applied:\n```ts\nit('will curry after', async () => {\n\n await forage.setItem({\n key: 'user',\n value: { name: 'Alice' }\n } as any)()\n\n const curry = (v: any) => v.toUpperCase()\n\n const user = await forage.getKeyValue({\n key: 'user',\n value: 'name'\n } as any)(curry)\n\n expect(user).toStrictEqual('ALICE')\n})\n```\n\nYou can also curry the value BEFORE it is used by localForage. This example is obviously quite trivial, but you may start to see a pattern emerge.\n```ts\n it('will curry before', async () => {\n\n // you can set objects or arrays or even huge base64 strings for values\n await forage.setItem({\n key: 'user',\n value: {\n name: 'Alice'\n }\n } as any)()\n\n const curry = (v: any) => v.toLowerCase()\n\n const user = await forage.getKeyValue({\n key: 'user',\n value: 'NAME',\n before: true\n } as any)(curry)\n\n expect(user).toStrictEqual('Alice')\n })\n```\n\nIf you want to have multiple \"stores\", you can easily do that too.\n\n\n## Extensions to localForage\nOf note are the extensions to the generic interface:\n - mergeItem (with a number of merge strategies available)\n - getKeyValue\n - deleteItemKey\n - hasKey\n - hasKeyValue\n\n## undefined / void 0 => always returns null!\n> Even if undefined is saved, null will be returned by getItem().\nThis is due to a limitation in localStorage, and for compatibility\nreasons localForage cannot store the value undefined.\n\n# Development\n## Testing\nTests are written with Jasmine flavor using Jest.\n\n## Docs\nThe docs are available as a static site in /docs\n\n## License\n(c) 2019-2020 - Daniel Thompson-Yvetot and contributors\n\nMIT\n","url":"https://github.com/tauri-apps/tauri-forage"},{"id":"github_tauri_apps_tauri_hotkey_rs","name":"tauri-hotkey-rs","description":null,"kind":"code","stars":9,"watchers":9,"subscribers":5,"openIssues":2,"forks":1,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-09T01:52:13Z","createdAt":"2021-02-14T04:49:18Z","text":"# Tauri Hotkey\n\nThis crate provides cross platform APIs to register keyboard hotkeys. This is a fork of [hotkey-rs](https://github.com/gamebooster/soundboard/tree/master/extern/hotkey-rs).\n\n## Platform support\n\n- Linux\n- macOS\n- Windows\n\n## License\nMIT\n","url":"https://github.com/tauri-apps/tauri-hotkey-rs"},{"id":"github_tauri_apps_tauri_dialog_rs","name":"tauri-dialog-rs","description":null,"kind":"unknown","stars":1,"watchers":1,"subscribers":4,"openIssues":0,"forks":1,"defaultBranch":"master","language":"C","topics":[],"isTemplate":false,"lastUpdated":"2021-06-06T00:39:20Z","createdAt":"2020-06-14T10:59:41Z","text":"# tauri-dialog-rs\n\nRust bindings to forked https://github.com/aaronmjacobs/Boxer.\n\n## Deprecation notice\n\nThis crate is no longer maintained. Tauri now uses [rfd](https://github.com/PolyMeilex/rfd).\n","url":"https://github.com/tauri-apps/tauri-dialog-rs"},{"id":"github_tauri_apps_tauri_inliner_rs","name":"tauri-inliner-rs","description":null,"kind":"code","stars":0,"watchers":0,"subscribers":4,"openIssues":2,"forks":0,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2021-04-12T08:30:46Z","createdAt":"2020-12-12T13:20:34Z","license":"MIT License","text":"# Tauri Inliner\n\nA Rust library for inlining assets in an HTML file. Based on the work on [inline-assets-rs](https://github.com/8176135/inline-assets-rs) and [inliner](https://github.com/remy/inliner).\n","url":"https://github.com/tauri-apps/tauri-inliner-rs"},{"id":"github_tauri_apps_tauri_inliner_rs","name":"tauri-inliner-rs","description":null,"kind":"code","stars":0,"watchers":0,"subscribers":4,"openIssues":2,"forks":0,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2021-04-12T08:30:46Z","createdAt":"2020-12-12T13:20:34Z","license":"MIT License","text":"# Tauri Inliner\n\nA Rust library for inlining assets in an HTML file. Based on the work on [inline-assets-rs](https://github.com/8176135/inline-assets-rs) and [inliner](https://github.com/remy/inliner).\n","url":"https://github.com/tauri-apps/tauri-inliner-rs"},{"id":"github_tauri_apps_rfcs","name":"rfcs","description":"A medium for proposing and repo of accepted RFCs.","kind":"unknown","stars":12,"watchers":12,"subscribers":6,"openIssues":1,"forks":1,"defaultBranch":"master","language":null,"topics":[],"isTemplate":false,"lastUpdated":"2021-07-16T22:50:55Z","createdAt":"2020-03-10T14:53:02Z","text":"# Tauri RFC Repository\nThis repo is dedicated to an RFC process, through which we have significant changes to the project undergo a transparent consideration and confirm changes by accepting them into the repo.\n\n## Process\n1) **Start a discussion.** Writing an RFC is a large investment of time, it's best to discuss it with the community to be sure it's worthwhile and to get it done right.\n2) **Fork this repo.** The review period of RFCs is held in the PR back into the repo.\n3) **Copy the template.** Move your copy of `template.md` into the `texts` folder, naming it in the scheme of `0000-feature.md`. Note: the number is literal, it needs to be adjusted just before merging.\n4) **Fill the template out.** Replace all relevant sections with explanations. Put care into the details, as it will serve as a reference through the development process.\n5) **Open a PR.** At this point, the RFC is open for comment. Discussion should happen in the comments of the PR. RFCs that are \"invalid\" (don't follow the format/proceedure, violate CoC, or are otherwise unable to be used) may be closed immediately, otherwise they will be left open for a minimum of 2 weeks before being accepted or rejected.\n6) **After the comment period,** a member of the Core Team will handle closing the RFC. If accepted, the RFC will be assigned a number and a tracking issue opened on the appropriate repo. Both details will be added to the RFC, then the PR will be merged.\n","url":"https://github.com/tauri-apps/rfcs"},{"id":"github_tauri_apps_tauri_theia","name":"tauri-theia","description":"Tauri Flavor of Theia","kind":"code","stars":28,"watchers":28,"subscribers":5,"openIssues":7,"forks":4,"defaultBranch":"dev","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2021-12-01T07:36:59Z","createdAt":"2020-05-09T18:07:35Z","license":"MIT License","text":"# Tauri Theia\n\n[Theia IDE](https://theia-ide.org/) packaged as a Tauri application.\n\n## To Use\n\nCurrently only working in Linux\n\n1. Clone this repository and open a terminal in the root of it. Make sure to use Node v10.x\n2. Install deps with `yarn`\n3. Package Theia server as an executable with `yarn theia:package`\n4. Run `yarn tauri build` to build the executable\n","url":"https://github.com/tauri-apps/tauri-theia"},{"id":"github_tauri_apps_tauri_toml","name":"tauri-toml","description":"Better TOML parsing and stringifying all in that familiar JSON interface.","kind":"unknown","stars":0,"watchers":0,"subscribers":1,"openIssues":0,"forks":1,"defaultBranch":"dev","language":"JavaScript","topics":[],"isTemplate":false,"lastUpdated":"2019-12-15T20:14:20Z","createdAt":"2019-11-30T11:18:10Z","license":"ISC License","text":"# @tauri-apps/toml\n\n## This is a fork of iarna-toml so that we can make some needed modifations for `tauri`.\n\nBetter TOML parsing and stringifying all in that familiar JSON interface.\n\n[![Coverage Status](https://coveralls.io/repos/github/iarna/iarna-toml/badge.svg)](https://coveralls.io/github/iarna/iarna-toml)\n\n# ** TOML 0.5.0 **\n\n### TOML Spec Support\n\nThe most recent version as of 2018-07-26: [v0.5.0](https://github.com/mojombo/toml/blob/master/versions/en/toml-v0.5.0.md)\n\n### Example\n\n```js\nconst TOML = require('@tauri-apps/toml')\nconst obj = TOML.parse(`[abc]\nfoo = 123\nbar = [1,2,3]`)\n/* obj =\n{abc: {foo: 123, bar: [1,2,3]}}\n*/\nconst str = TOML.stringify(obj)\n/* str =\n[abc]\nfoo = 123\nbar = [ 1, 2, 3 ]\n*/\n```\n\nVisit the project github [for more examples](https://github.com/iarna/iarna-toml/tree/latest/examples)!\n\n\n## Why @tauri-apps/toml\n\n* See [TOML-SPEC-SUPPORT](https://shared.by.re-becca.org/misc/TOML-SPEC-SUPPORT.html) for a comparison of which TOML features\n are supported by the various Node.js TOML parsers.\n* BigInt support on Node 10!\n* 100% test coverage.\n* Faster parsing, even if you only use TOML 0.4.0, it's as much as 100 times\n faster than `toml` and 3 times faster than `toml-j0.4`. However a recent\n newcomer [`@ltd/j-toml`](https://www.npmjs.com/package/@ltd/j-toml) has\n appeared with 0.5 support and astoundingly fast parsing speeds for large\n text blocks. All I can say is you'll have to test your specific work loads\n if you want to know which of @tauri-apps/toml and @ltd/j-toml is faster for\n you, as we currently excell in different areas\n* Careful adherence to spec. Tests go beyond simple coverage.\n* Smallest parser bundle (if you use `@tauri-apps/toml/parse-string`).\n* No deps.\n* Detailed and easy to read error messages‼\n\n```console\n> TOML.parse(src)\nError: Unexpected character, expecting string, number, datetime, boolean, inline array or inline table at row 6, col 5, pos 87:\n5: \"abc\\\"\" = { abc=123,def=\"abc\" }\n6> foo=sdkfj\n ^\n7:\n```\n\n## TOML.parse(str) → Object [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse.js)\n\nAlso available with: `require('@tauri-apps/toml/parse-string')`\n\nSynchronously parse a TOML string and return an object.\n\n\n## TOML.stringify(obj) → String [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/stringify.js)\n\nAlso available with: `require('@tauri-apps/toml/stringify)`\n\nSerialize an object as TOML.\n\n## [your-object].toJSON\n\nIf an object `TOML.stringify` is serializing has a `toJSON` method then it\nwill call it to transform the object before serializing it. This matches\nthe behavior of `JSON.stringify`.\n\nThe one exception to this is that `toJSON` is not called for `Date` objects\nbecause `JSON` represents dates as strings and TOML can represent them natively.\n\n[`moment`](https://www.npmjs.com/package/moment) objects are treated the\nsame as native `Date` objects, in this respect.\n\n## TOML.stringify.value(obj) -> String\n\nAlso available with: `require('@tauri-apps/toml/stringify').value`\n\nSerialize a value as TOML would. This is a fragment and not a complete\nvalid TOML document.\n\n## Promises and Streaming\n\nThe parser provides alternative async and streaming interfaces, for times\nthat you're working with really absurdly big TOML files and don't want to\ntie-up the event loop while it parses.\n\n### TOML.parse.async(str[, opts]) → Promise(Object) [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse-async.js)\n\nAlso available with: `require('@tauri-apps/toml/parse-async')`\n\n`opts.blocksize` is the amount text to parser per pass through the event loop. Defaults to 40kb.\n\nAsynchronously parse a TOML string and return a promise of the resulting object.\n\n### TOML.parse.stream(readable) → Promise(Object) [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse-stream-readable.js)\n\nAlso available with: `require('@tauri-apps/toml/parse-stream')`\n\nGiven a readable stream, parse it as it feeds us data. Return a promise of the resulting object.\n\n### readable.pipe(TOML.parse.stream()) → Transform [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse-stream-through.js)\n\nAlso available with: `require('@tauri-apps/toml/parse-stream')`\n\nReturns a transform stream in object mode. When it completes, emit the\nresulting object. Only one object will ever be emitted.\n\n## Lowlevel Interface [(example)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse-lowlevel.js) [(example w/ parser debugging)](https://github.com/iarna/iarna-toml/blob/latest/examples/parse-lowlevel-debug.js)\n\nYou construct a parser object, per TOML file you want to process:\n\n```js\nconst TOMLParser = require('@tauri-apps/toml/lib/toml-parser.js')\nconst parser = new TOMLParser()\n```\n\nThen you call the `parse` method for each chunk as you read them, or in a\nsingle call:\n\n```js\nparser.parse(`hello = 'world'`)\n```\n\nAnd finally, you call the `finish` method to complete parsing and retrieve\nthe resulting object.\n\n```js\nconst data = parser.finish()\n```\n\nBoth the `parse` method and `finish` method will throw if they find a\nproblem with the string they were given. Error objects thrown from the\nparser have `pos`, `line` and `col` attributes. `TOML.parse` adds a visual\nsummary of where in the source string there were issues using\n`parse-pretty-error` and you can too:\n\n```js\nconst prettyError = require('./parse-pretty-error.js')\nconst newErr = prettyError(err, sourceString)\n```\n\n## What's Different\n\nVersion 2 of this module supports TOML 0.5.0. Other modules currently\npublished to the npm registry support 0.4.0. 0.5.0 is mostly backwards\ncompatible with 0.4.0, but if you have need, you can install @tauri-apps/toml@1\nto get a version of this module that supports 0.4.0. Please see the\n[CHANGELOG](CHANGELOG.md#2.0.0) for details on exactly whats changed.\n\n## TOML we can't do\n\n* `-nan` is a valid TOML value and is converted into `NaN`. There is no way to\n produce `-nan` when stringifying. Stringification will produce positive `nan`.\n* Detecting and erroring on invalid utf8 documents: This is because Node's\n UTF8 processing converts invalid sequences into the placeholder character\n and does not have facilities for reporting these as errors instead. We\n _can_ detect the placeholder character, but it's valid to intentionally\n include them in documents, so erroring on them is not great.\n* On versions of Node < 10, very large Integer values will lose precision.\n On Node >=10, bigints are used.\n* Floating/local dates and times are still represented by JavaScript Date\n objects, which don't actually support these concepts. The objects\n returned have been modified so that you can determine what kind of thing\n they are (with `isFloating`, `isDate`, `isTime` properties) and that\n their ISO representation (via `toISOString`) is representative of their\n TOML value. They will correctly round trip if you pass them to\n `TOML.stringify`.\n* Binary, hexadecimal and octal values are converted to ordinary integers and\n will be decimal if you stringify them.\n\n## Changes\n\nI write a by hand, honest-to-god,\n[CHANGELOG](https://github.com/iarna/iarna-toml/blob/latest/CHANGELOG.md)\nfor this project. It's a description of what went into a release that you\nthe consumer of the module could care about, not a list of git commits, so\nplease check it out!\n\n## Benchmarks\n\nYou can run them yourself with:\n\n```console\n$ npm run benchmark\n```\n\nThe results below are from my laptop using Node 11.10.0. The library\nversions tested were `@tauri-apps/toml@2.2.2`, `toml-j0.4@1.1.1`, `toml@3.0.0`,\n`@sgarciac/bombadil@2.1.0` and `@ltd/j-toml@0.5.47`. The speed value is\nmegabytes-per-second that the parser can process of that document type.\nBigger is better. The percentage after average results is the margin of error.\n\nAs this table is getting a little wide, with how npm and github display it,\nyou can also view it seperately in the [BENCHMARK](https://shared.by.re-becca.org/misc/BENCHMARK.html) document.\n\n| | @tauri-apps/toml | | toml-j0.4 | | toml | | @sgarciac/bombadil | | @ltd/j-toml | |\n| - | ----------- | - | --------- | - | ---- | - | ------------------ | - | ----------- | - |\n| Overall | 25MB/sec | 0.55% | 7MB/sec | 1.39% | 0.2MB/sec | 3.47% | - | - | 38MB/sec | 1.37% |\n| Spec Example: v0.4.0 | 23MB/sec | 0.87% | 10MB/sec | 0.62% | 1MB/sec | 1.89% | 1.7MB/sec | 1.03% | 35MB/sec | 1.32% |\n| Spec Example: Hard Unicode | 57MB/sec | 1.46% | 16MB/sec | 0.66% | 2MB/sec | 2.25% | 0.8MB/sec | 0.57% | 93MB/sec | 1.79% |\n| Types: Array, Inline | 7.2MB/sec | 1.60% | 3.2MB/sec | 0.77% | 0.1MB/sec | 1.84% | 1.7MB/sec | 0.56% | 4.1MB/sec | 14.48% |\n| Types: Array | 6.9MB/sec | 0.47% | 5.8MB/sec | 0.46% | 0.1MB/sec | 3.67% | 1.4MB/sec | 0.76% | 2.5MB/sec | 8.19% |\n| Types: Boolean, | 22MB/sec | 0.85% | 8.5MB/sec | 0.55% | 0.2MB/sec | 1.83% | 2.1MB/sec | 1.29% | 5.6MB/sec | 0.58% |\n| Types: Datetime | 18MB/sec | 0.56% | 11MB/sec | 0.80% | 0.3MB/sec | 1.55% | 0.8MB/sec | 0.51% | 4.5MB/sec | 0.66% |\n| Types: Float | 9.2MB/sec | 0.71% | 5.2MB/sec | 1.12% | 0.3MB/sec | 2.04% | 2.6MB/sec | 0.86% | 3.7MB/sec | 0.61% |\n| Types: Int | 6.4MB/sec | 0.44% | 3.9MB/sec | 0.56% | 0.1MB/sec | 1.65% | 1.7MB/sec | 1.15% | 1.5MB/sec | 4.06% |\n| Types: Literal String, 7 char | 26MB/sec | 0.62% | 8.1MB/sec | 1.00% | 0.3MB/sec | 1.48% | 2.9MB/sec | 0.58% | 6MB/sec | 0.52% |\n| Types: Literal String, 92 char | 41MB/sec | 0.80% | 11MB/sec | 1.20% | 0.4MB/sec | 2.38% | 15MB/sec | 0.84% | 23MB/sec | 0.58% |\n| Types: Literal String, Multiline, 1079 char | 21MB/sec | 0.28% | 7.2MB/sec | 1.62% | 1.3MB/sec | 3.05% | 55MB/sec | 0.53% | 332MB/sec | 0.46% |\n| Types: Basic String, 7 char | 26MB/sec | 0.56% | 6.6MB/sec | 0.61% | 0.2MB/sec | 4.70% | 2.7MB/sec | 0.68% | 3.3MB/sec | 0.47% |\n| Types: Basic String, 92 char | 41MB/sec | 0.63% | 8MB/sec | 0.51% | 0.1MB/sec | 1.57% | 14MB/sec | 0.66% | 21MB/sec | 0.43% |\n| Types: Basic String, 1079 char | 21MB/sec | 0.36% | 6MB/sec | 0.81% | 0.1MB/sec | 1.81% | 51MB/sec | 0.53% | 13MB/sec | 0.62% |\n| Types: Table, Inline | 9.8MB/sec | 0.47% | 4.6MB/sec | 0.81% | 0.1MB/sec | 1.82% | 1.7MB/sec | 0.75% | 2.9MB/sec | 4.82% |\n| Types: Table | 6.9MB/sec | 0.43% | 4.9MB/sec | 0.46% | 0.1MB/sec | 3.59% | 1.6MB/sec | 0.88% | 4.4MB/sec | 0.53% |\n| Scaling: Array, Inline, 1000 elements | 33MB/sec | 2.15% | 2.5MB/sec | 1.07% | 0.1MB/sec | 3.57% | 1.8MB/sec | 0.64% | 8.7MB/sec | 4.12% |\n| Scaling: Array, Nested, 1000 deep | 1.6MB/sec | 2.50% | 1.2MB/sec | 0.49% | 0.1MB/sec | 3.62% | - | - | 1MB/sec | 3.79% |\n| Scaling: Literal String, 40kb | 56MB/sec | 0.58% | 12MB/sec | 1.03% | 3.6MB/sec | 4.00% | 17MB/sec | 0.54% | 498MB/sec | 0.52% |\n| Scaling: Literal String, Multiline, 40kb | 58MB/sec | 0.38% | 6.4MB/sec | 0.54% | 0.2MB/sec | 1.72% | 15MB/sec | 0.74% | 197MB/sec | 0.54% |\n| Scaling: Basic String, Multiline, 40kb | 57MB/sec | 1.03% | 7.2MB/sec | 1.22% | 3.4MB/sec | 4.24% | 15MB/sec | 0.75% | 840MB/sec | 0.52% |\n| Scaling: Basic String, 40kb | 57MB/sec | 0.43% | 8.6MB/sec | 0.57% | 0.2MB/sec | 1.71% | 17MB/sec | 0.51% | 394MB/sec | 0.54% |\n| Scaling: Table, Inline, 1000 elements | 27MB/sec | 0.46% | 7.5MB/sec | 0.71% | 0.3MB/sec | 2.24% | 3MB/sec | 0.74% | 2.3MB/sec | 0.81% |\n| Scaling: Table, Inline, Nested, 1000 deep | 7.8MB/sec | 0.61% | 4.3MB/sec | 0.83% | 0.1MB/sec | 2.93% | - | - | 1.2MB/sec | 13.45% |\n\n## Tests\n\nThe test suite is maintained at 100% coverage: [![Coverage Status](https://coveralls.io/repos/github/iarna/iarna-toml/badge.svg)](https://coveralls.io/github/iarna/iarna-toml)\n\nThe spec was carefully hand converted into a series of test framework\nindependent (and mostly language independent) assertions, as pairs of TOML\nand YAML files. You can find those files here:\n[spec-test](https://github.com/iarna/iarna-toml/blob/latest/test/spec-test/).\nA number of examples of invalid Unicode were also written, but are difficult\nto make use of in Node.js where Unicode errors are silently hidden. You can\nfind those here: [spec-test-disabled](https://github.com/iarna/iarna-toml/blob/latest/test/spec-test-disabled/).\n\nFurther tests were written to increase coverage to 100%, these may be more\nimplementation specific, but they can be found in [coverage](https://github.com/iarna/iarna-toml/blob/latest/test/coverage.js) and\n[coverage-error](https://github.com/iarna/iarna-toml/blob/latest/test/coverage-error.js).\n\nI've also written some quality assurance style tests, which don't contribute\nto coverage but do cover scenarios that could easily be problematic for some\nimplementations can be found in:\n[test/qa.js](https://github.com/iarna/iarna-toml/blob/latest/test/qa.js) and\n[test/qa-error.js](https://github.com/iarna/iarna-toml/blob/latest/test/qa-error.js).\n\nAll of the official example files from the TOML spec are run through this\nparser and compared to the official YAML files when available. These files are from the TOML spec as of:\n[357a4ba6](https://github.com/toml-lang/toml/tree/357a4ba6782e48ff26e646780bab11c90ed0a7bc)\nand specifically are:\n\n* [github.com/toml-lang/toml/tree/357a4ba6/examples](https://github.com/toml-lang/toml/tree/357a4ba6782e48ff26e646780bab11c90ed0a7bc/examples)\n* [github.com/toml-lang/toml/tree/357a4ba6/tests](https://github.com/toml-lang/toml/tree/357a4ba6782e48ff26e646780bab11c90ed0a7bc/tests)\n\nThe stringifier is tested by round-tripping these same files, asserting that\n`TOML.parse(sourcefile)` deepEqual\n`TOML.parse(TOML.stringify(TOML.parse(sourcefile))`. This is done in\n[test/roundtrip-examples.js](https://github.com/iarna/iarna-toml/blob/latest/test/round-tripping.js)\nThere are also some tests written to complete coverage from stringification in:\n[test/stringify.js](https://github.com/iarna/iarna-toml/blob/latest/test/stringify.js)\n\nTests for the async and streaming interfaces are in [test/async.js](https://github.com/iarna/iarna-toml/blob/latest/test/async.js) and [test/stream.js](https://github.com/iarna/iarna-toml/blob/latest/test/stream.js) respectively.\n\nTests for the parsers debugging mode live in [test/devel.js](https://github.com/iarna/iarna-toml/blob/latest/test/devel.js).\n\nAnd finally, many more stringification tests were borrowed from [@othiym23](https://github.com/othiym23)'s\n[toml-stream](https://npmjs.com/package/toml-stream) module. They were fetched as of\n[b6f1e26b572d49742d49fa6a6d11524d003441fa](https://github.com/othiym23/toml-stream/tree/b6f1e26b572d49742d49fa6a6d11524d003441fa/test) and live in\n[test/toml-stream](https://github.com/iarna/iarna-toml/blob/latest/test/toml-stream/).\n\n## Improvements to make\n\n* In stringify:\n * Any way to produce comments. As a JSON stand-in I'm not too worried\n about this. That said, a document orientated fork is something I'd like\n to look at eventually…\n * Stringification could use some work on its error reporting. It reports\n _what's_ wrong, but not where in your data structure it was.\n* Further optimize the parser:\n * There are some debugging assertions left in the main parser, these should be moved to a subclass.\n * Make the whole debugging parser thing work as a mixin instead of as a superclass.\n","url":"https://github.com/tauri-apps/tauri-toml"},{"id":"github_tauri_apps_realworld","name":"realworld","description":"Realworld apps made with Tauri: Proof of Agnosis.","kind":"unknown","stars":4,"watchers":4,"subscribers":5,"openIssues":1,"forks":0,"defaultBranch":"dev","language":"JavaScript","topics":[],"isTemplate":false,"lastUpdated":"2021-03-02T14:54:39Z","createdAt":"2020-02-05T22:02:37Z","license":"MIT License","text":"# Tauri x Realworld apps\n\nThis project is an experiment to demonstrate how easy you can bundle an existing frontend app with Tauri, whichever the framework you're using, without having to change a single line from the codebase.\n\nThe main script (build.js) simply consists in a pipeline that will clone, install dependencies, build the application, initialize Tauri then bundle the application. \n\n## Setup\n\n1. Take a look at the Wiki to setup Tauri: https://github.com/tauri-apps/tauri/wiki\n2. Have Git, Node and NPM installed\n3. Clone and install this project dependencies, either with NPM or Yarn:\n```bash\ngit clone git@github.com:tauri-apps/realworld.git\ncd realworld\n\nyarn install\n# OR\nnpm install\n```\n\n## Usage\n\n`node build {{app.repo}}`\nThis will apply the pipeline on a single application from apps.yaml. Copy/paste a `repo` property from the wanted application and let it build.\n\n`node build`\nThis will apply the pipeline on _every_ application from apps.yaml. Unless you have some spare time, enough disk space, a nice CPU and unlimited bandwidth, you should avoid to do it (and ensure the pipeline at least works for a single project in a first time).\n\n## Details about apps.yaml\n\nCommented apps have not been successfully bundled (yet), either because of the build or the bundle phase failing.\nA detail about what's wrong is displayed above the app title. \n","url":"https://github.com/tauri-apps/realworld"},{"id":"github_tauri_apps_governance_and_guidance","name":"governance-and-guidance","description":null,"kind":"unknown","stars":3,"watchers":3,"subscribers":16,"openIssues":7,"forks":2,"defaultBranch":"master","language":null,"topics":[],"isTemplate":false,"lastUpdated":"2021-03-15T09:00:16Z","createdAt":"2019-09-04T18:07:56Z","license":"MIT License","text":"# Governance and Guidance\n","url":"https://github.com/tauri-apps/governance-and-guidance"},{"id":"github_tauri_apps_tauri_search_bot","name":"tauri-search-bot","description":"Tauri's Discord Bot","kind":"unknown","stars":1,"watchers":1,"subscribers":4,"openIssues":10,"forks":0,"defaultBranch":"main","language":"JavaScript","topics":[],"isTemplate":false,"lastUpdated":"2021-08-09T07:21:36Z","createdAt":"2021-02-09T21:05:37Z","license":"MIT License","text":"# tauri-search-bot","url":"https://github.com/tauri-apps/tauri-search-bot"},{"id":"github_tauri_apps_webkit_gtk_rs","name":"webkit2gtk-rs","description":"WebKit2 bindings and wrappers for Rust","kind":"code","stars":79,"watchers":79,"subscribers":12,"openIssues":13,"forks":21,"defaultBranch":"crate","language":"Rust","topics":["hacktoberfest"],"isTemplate":false,"lastUpdated":"2022-02-13T17:54:57Z","createdAt":"2016-09-14T17:22:14Z","license":"MIT License","text":"# webkit2gtk\n\n__Rust__ bindings and wrappers for __webkit2gtk__.\n\n## Building\n\n__webkit2gtk-rs__ expects __GTK+__, __GLib__ and __webkit2gtk__ development files to be installed on your system.\nSee the [requirements page](http://gtk-rs.org/docs/requirements.html).\n\n## Using\n\n```toml\n[dependencies]\nwebkit2gtk-rs = \"0.15\"\n```\n\n## License\n\n__webkit2gtk-rs__ is available under the MIT License, please refer to it.\n","url":"https://github.com/tauri-apps/webkit2gtk-rs"},{"id":"github_tauri_apps_javascriptcore_rs","name":"javascriptcore-rs","description":"JavaScriptCore bindings and wrappers for Rust","kind":"code","stars":33,"watchers":33,"subscribers":11,"openIssues":1,"forks":16,"defaultBranch":"crate","language":"Rust","topics":[],"isTemplate":false,"lastUpdated":"2022-02-13T21:58:05Z","createdAt":"2016-09-18T21:14:54Z","license":"MIT License","text":"# javascriptcore\n\n__Rust__ bindings and wrappers for __javascriptcore__.\n\n## Using\n\n```toml\n[dependencies]\njavascriptcore-rs = \"0.14\"\n```\n\n## License\n\n__javascriptcore-rs__ is available under the MIT License, please refer to it.\n","url":"https://github.com/tauri-apps/javascriptcore-rs"},{"id":"github_tauri_apps_awesome_tauri","name":"awesome-tauri","description":"🚀 Awesome Tauri Apps, Plugins and Resources","kind":"unknown","stars":63,"watchers":63,"subscribers":11,"openIssues":2,"forks":9,"defaultBranch":"dev","language":null,"topics":["awesome","awesome-list","tauri"],"isTemplate":false,"lastUpdated":"2022-02-14T07:10:17Z","createdAt":"2022-01-22T16:25:58Z","license":"MIT License","text":"\n\n

Awesome Tauri

\n\n

\nThis is where we collect all of the best stuff from the ecosystem and community.\n

\n\n\nAwesome\n\n

\n\n## Table of Contents\n- [Get Started](#get-started)\n- [Plugins](#plugins)\n- [Integrations](#integrations)\n- [Apps](#apps)\n- [Tutorials](#tutorials)\n- [Articles](#articles)\n\n## Get Started\n\n- [Introduction](https://tauri.studio/docs/development/intro) - Official introduction to Tauri.\n- [create-tauri-app](https://github.com/tauri-apps/tauri/tree/next/tooling/create-tauri-app) - Rapidly scaffold your Tauri app.\n\n### Templates\n- [tauri-svelte-template](https://github.com/probablykasper/tauri-svelte-template) - Svelte template with cross-platform GitHub action builds, macOS 10.13+ support, Vite, TypeScript, Svelte Preprocess, hot module replacement, ESLint and Prettier.\n\n## Plugins\n\n- [tauri-plugin-authenticator](https://github.com/tauri-apps/tauri-plugin-authenticator) ![official](https://img.shields.io/badge/-official-FFC131) - Interface with hardware security keys.\n- [tauri-plugin-log](https://github.com/tauri-apps/tauri-plugin-log) ![official](https://img.shields.io/badge/-official-FFC131) - Configurable logging.\n- [tauri-plugin-sql](https://github.com/tauri-apps/tauri-plugin-sql) ![official](https://img.shields.io/badge/-official-FFC131) - Interface with SQL databases.\n- [tauri-plugin-store](https://github.com/tauri-apps/tauri-plugin-store) ![official](https://img.shields.io/badge/-official-FFC131) - Persistent key value storage.\n- [tauri-plugin-stronghold](https://github.com/tauri-apps/tauri-plugin-stronghold) ![official](https://img.shields.io/badge/-official-FFC131) - Encrypted, secure, p2p database.\n- [tauri-plugin-window-state](https://github.com/tauri-apps/tauri-plugin-window-state) ![official](https://img.shields.io/badge/-official-FFC131) - Persist window sizes and positions.\n- [tauri-plugin-vibrancy](https://github.com/tauri-apps/tauri-plugin-vibrancy) ![official](https://img.shields.io/badge/-official-FFC131) - Make your Tauri/TAO windows vibrant.\n- [tauri-plugin-shadows](https://github.com/tauri-apps/tauri-plugin-shadows) ![official](https://img.shields.io/badge/-official-FFC131) - Add native shadows to your Tauri/TAO windows.\n- [tauri-plugin-positioner](https://github.com/JonasKruckenberg/tauri-plugin-positioner) - Move windows to common locations.\n \n## Integrations\n\n- [vue-cli-plugin-tauri](https://github.com/tauri-apps/vue-cli-plugin-tauri) ![official](https://img.shields.io/badge/-official-FFC131) - Turn your Vue SPA into a lightweight cross-platform desktop app.\n- [vite-plugin-tauri](https://github.com/amrbashir/vite-plugin-tauri) - Integrate Tauri in a Vite project to build cross-platform apps.\n- [axios-tauri-adapter](https://git.kaki87.net/KaKi87/axios-tauri-adapter) - `axios` adapter for the `@tauri-apps/api/http` module.\n- [svelte-tauri-filedrop](https://github.com/probablykasper/svelte-tauri-filedrop) - File drop handling component for Svelte.\n\n## Apps\n\n### Open Source\n\n- [UsTaxes](https://github.com/ustaxes/ustaxes) - Free, private, open-source US tax filings.\n- [Xplorer](https://github.com/kimlimjustin/xplorer) - Customizable, modern and cross-platform File Explorer.\n- [Clash Verge](https://github.com/zzzgydi/clash-verge) - Rule based proxy for Mac and Windows based on `clash`.\n- [Authme Lite](https://github.com/Levminer/authme-lite) - Two-factor (2FA) authentication app for desktop.\n- [BS Redis Desktop Client](https://github.com/fuyoo/bs-redis-desktop-client) - The Best Surprise Redis Desktop Client.\n- [Kadium](https://github.com/probablykasper/kadium) - App for staying ontop of YouTube channel uploads.\n- [Mr Tagger](https://github.com/probablykasper/mr-tagger) - Music file tagging app.\n- [Time Machine Inspector](https://github.com/probablykasper/time-machine-inspector) - Find out what's taking up your Time Machine backup space.\n- [Identia](https://github.com/iohzrd/identia) - Decentralized social media on IPFS.\n- [Calciumdibromid](https://codeberg.org/Calciumdibromid/CaBr2) - Generate \"experiment wise safety sheets\" in compliance to European law.\n\n### Closed Source\n\n## Tutorials\n\n## Articles\n","url":"https://github.com/tauri-apps/awesome-tauri"}] \ No newline at end of file diff --git a/packages/tauri-search/src/generated/sitemap-tauri-docs-dev.json b/packages/tauri-search/src/generated/sitemap-tauri-docs-dev.json index 83aaca7..8a96c0a 100644 --- a/packages/tauri-search/src/generated/sitemap-tauri-docs-dev.json +++ b/packages/tauri-search/src/generated/sitemap-tauri-docs-dev.json @@ -1 +1 @@ -{"dir":"docs","files":[{"name":"architecture.md","size":11441,"sha":"4662fc95e05bb6322be72f11e510907b05d2c23b","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture.md"},{"name":"faq.md","size":683,"sha":"d34a2b65679a4d74243b353b03f6302e8f0b6839","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/faq.md"}],"children":[{"dir":"docs/about","files":[{"name":"architecture.md","size":11441,"sha":"4662fc95e05bb6322be72f11e510907b05d2c23b","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/about/architecture.md"},{"name":"book.md","size":11030,"sha":"9c73ed072e0f10b2415b200969125038de792ad5","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/about/book.md"},{"name":"governance.md","size":2206,"sha":"5d32aef726d78b1128f7550c6eea6ead829869f4","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/about/governance.md"},{"name":"intro.md","size":3688,"sha":"beab1e81b674cb4a444258aaec9f5cd112dbe7a6","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/about/intro.md"},{"name":"security.md","size":6411,"sha":"1a08b26e915e3b215c4a77a4d9ec7d3351c8865e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/about/security.md"}],"children":[]},{"dir":"docs/architecture","files":[{"name":"build-tools.md","size":123,"sha":"ea4e9229d16bd3cb3955b1809d1d1f943a0fff3d","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/build-tools.md"},{"name":"frontend-frameworks.md","size":129,"sha":"2ce72a9138df4cc87328aa85fc8e9208f6f05463","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/frontend-frameworks.md"}],"children":[{"dir":"docs/architecture/patterns","files":[{"name":"about-patterns.md","size":636,"sha":"c0581d2eb7d593804742b7c5d544edc22f313816","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/patterns/about-patterns.md"},{"name":"bridge.md","size":2607,"sha":"5619a30ac710c9552571d35ff4ac5fdd4485104c","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/patterns/bridge.md"},{"name":"cloudbridge.md","size":2175,"sha":"72184c395ee32d5de601423caef5261901a3c6ea","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/patterns/cloudbridge.md"},{"name":"cloudish.md","size":2085,"sha":"7697ba5094e2d636e83d07d57d425ef581c0ff0e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/patterns/cloudish.md"},{"name":"glui.md","size":2070,"sha":"1a2484b6414c233ca7c3636b78e130139acdd125","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/patterns/glui.md"},{"name":"hermit.md","size":1956,"sha":"bfff74bcfa26a55724ae681ee19b097852648b01","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/patterns/hermit.md"},{"name":"lockdown.md","size":1807,"sha":"d09c8a7651d954c62c496641c7904925a91d3e22","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/patterns/lockdown.md"},{"name":"multiwin.md","size":1881,"sha":"f815734e2b9de5ec2c838fe676a0cf7b8004faef","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/patterns/multiwin.md"}],"children":[]}]},{"dir":"docs/building","files":[{"name":"anti-bloat.md","size":4958,"sha":"8105cafb77ceb65a6bbc9b5365828d4a75ce28ea","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/building/anti-bloat.md"},{"name":"cross-platform.md","size":103,"sha":"fc7ada90f18b51c65b5685a6022c64286bc0662e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/building/cross-platform.md"},{"name":"debian.md","size":1176,"sha":"5d581d2b96e072d142da3ef8c566274fd73bb8c0","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/building/debian.md"},{"name":"introduction.md","size":300,"sha":"ba24668c624d14d7af656654fb1b45851cec5a70","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/building/introduction.md"},{"name":"sidecar.md","size":3264,"sha":"d3a25383d9daddf3edb9c879dbdc8bd020ee0def","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/building/sidecar.md"}],"children":[]},{"dir":"docs/community","files":[{"name":"ci-cd.md","size":4659,"sha":"6d213c39bcdb5e5523c48443b5dbee493a295cfb","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/community/ci-cd.md"},{"name":"contributor-guide.md","size":1813,"sha":"f6397d06c792e413cb58a8b80c6459261ee81a14","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/community/contributor-guide.md"}],"children":[]},{"dir":"docs/debugging","files":[{"name":"debugging.md","size":2394,"sha":"981ea4f056ded285ca9000394c2427939bd6f501","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/debugging/debugging.md"}],"children":[]},{"dir":"docs/development","files":[{"name":"development-cycle.md","size":1534,"sha":"9a93dca6cb381bb6dcd3c2a132665b39b342f552","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/development/development-cycle.md"},{"name":"security.md","size":14993,"sha":"fc6fba103219cdab6bdce161ef5c46dcfd1a17a8","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/development/security.md"},{"name":"updating-dependencies.md","size":1412,"sha":"cc0e0b7b215803da242d80db787c9f2cffbf7e00","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/development/updating-dependencies.md"}],"children":[]},{"dir":"docs/distribution","files":[{"name":"macos.md","size":3733,"sha":"de4ddc8eb721c2e764c65a58d187c9b83a82b69a","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/macos.md"},{"name":"publishing.md","size":965,"sha":"dd6d4848656d27c8f58d93dd4878baadfbb8a0f3","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/publishing.md"},{"name":"sign-macos.md","size":8075,"sha":"020d3561a93d647dbc1596585f0228b4b0e7767f","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/sign-macos.md"},{"name":"sign-windows.md","size":7179,"sha":"c7d551cbd3b66a64d1287ee4b395460ba91fa318","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/sign-windows.md"},{"name":"updater.md","size":10528,"sha":"bbd29cf85f451debd56c12369e309654f72b705e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/updater.md"}],"children":[]},{"dir":"docs/getting-started","files":[{"name":"beginning-tutorial.md","size":4613,"sha":"9f91ace6f1fc36faf8ac63f381637db2f4ee87f0","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/getting-started/beginning-tutorial.md"},{"name":"prerequisites.md","size":708,"sha":"c714cfbe0659f6c8ca47a9f88fd3c0fc911ad37d","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/getting-started/prerequisites.md"},{"name":"setting-up-linux.md","size":5005,"sha":"1357a7e274c997d214cfaea1efb6fde33aad7506","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/getting-started/setting-up-linux.md"},{"name":"setting-up-macos.md","size":2777,"sha":"c67602b492145bacbd2cd461621ef95493d779fa","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/getting-started/setting-up-macos.md"},{"name":"setting-up-windows.md","size":3236,"sha":"0482264724ec57e313d38a1713d689ba998163f4","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/getting-started/setting-up-windows.md"}],"children":[]},{"dir":"docs/guides","files":[{"name":"cli.md","size":4607,"sha":"6afeba66519917acc74a5b52bf9a221ea60e667e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/cli.md"},{"name":"command.md","size":6319,"sha":"3b3d643e80285cea010e802df216bf2ac99927f9","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/command.md"},{"name":"events.md","size":4446,"sha":"ed0d6d0e122ba0f1dd11492a5a4c19dcfde9430c","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/events.md"},{"name":"icons.md","size":1326,"sha":"cc42057ce4fa47e3b24a5714045716a3bc1ed8cc","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/icons.md"},{"name":"menu.md","size":4223,"sha":"b82a2dcc83714851d949cfecaf2f9b39c77ae152","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/menu.md"},{"name":"multiwindow.md","size":77,"sha":"46b84b35625fd9c0080acb0b82ef6accf70ab354","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/multiwindow.md"},{"name":"plugin.md","size":3353,"sha":"0297fe6c19b2cf54fb299a9bc8ba433b2e369c52","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/plugin.md"},{"name":"splashscreen.md","size":3185,"sha":"81d444a73a24d7bcfcfd12071a1c251fa8121ee0","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/splashscreen.md"},{"name":"system-tray.md","size":5050,"sha":"02f29f5985f1914c386714ce8e6e28361c872b71","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/system-tray.md"},{"name":"window-customization.md","size":2363,"sha":"d1a4eed20e2b918865e88530a5ecf4a06bcd341e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/window-customization.md"}],"children":[]},{"dir":"docs/testing","files":[],"children":[{"dir":"docs/testing/webdriver","files":[{"name":"ci.md","size":3249,"sha":"214e9c91c106922c414edb0ec630c4b10f76d848","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/webdriver/ci.md"},{"name":"introduction.md","size":2874,"sha":"dc87ecd2de01f2c6357654777cf41a1be0b1e12e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/webdriver/introduction.md"}],"children":[{"dir":"docs/testing/webdriver/example","files":[{"name":"selenium.md","size":7038,"sha":"361973dda3566a035cef36202c7e198dd1934b94","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/webdriver/example/selenium.md"},{"name":"setup.md","size":6694,"sha":"2e0d3471f0f8fc2cf97351df0d891d0fc39ae08d","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/webdriver/example/setup.md"},{"name":"webdriverio.md","size":8233,"sha":"0bfc7b8a9e19e8cbbda638c31942c7ab4b92282e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/webdriver/example/webdriverio.md"}],"children":[]}]}]}]} \ No newline at end of file +{"dir":"docs","files":[{"name":"architecture.md","size":11491,"sha":"fd5b5c3ffa3c0eda2104bee19efc440720204e7c","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture.md"},{"name":"faq.md","size":684,"sha":"6dbedb01e41dd74e91e3a4b962b4c9e774b45e8d","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/faq.md"}],"children":[{"dir":"docs/about","files":[{"name":"architecture.md","size":11441,"sha":"4662fc95e05bb6322be72f11e510907b05d2c23b","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/about/architecture.md"},{"name":"book.md","size":11030,"sha":"9c73ed072e0f10b2415b200969125038de792ad5","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/about/book.md"},{"name":"governance.md","size":2206,"sha":"5d32aef726d78b1128f7550c6eea6ead829869f4","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/about/governance.md"},{"name":"intro.md","size":3688,"sha":"beab1e81b674cb4a444258aaec9f5cd112dbe7a6","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/about/intro.md"},{"name":"security.md","size":6411,"sha":"1a08b26e915e3b215c4a77a4d9ec7d3351c8865e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/about/security.md"}],"children":[]},{"dir":"docs/architecture","files":[{"name":"build-tools.md","size":123,"sha":"ea4e9229d16bd3cb3955b1809d1d1f943a0fff3d","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/build-tools.md"},{"name":"frontend-frameworks.md","size":129,"sha":"2ce72a9138df4cc87328aa85fc8e9208f6f05463","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/frontend-frameworks.md"}],"children":[{"dir":"docs/architecture/patterns","files":[{"name":"brownfield.md","size":1972,"sha":"2a2934b54942c106620a681f5e4775639a6caec9","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/patterns/brownfield.md"},{"name":"isolation.md","size":7787,"sha":"d843d2f4f600f4369fd1b482a7a625e445044ed6","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/patterns/isolation.md"}],"children":[]},{"dir":"docs/architecture/recipes","files":[{"name":"about-recipes.md","size":631,"sha":"05d011ae3f130abb94a8440a1a50ff0ff2367ee8","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/recipes/about-recipes.md"},{"name":"bridge.md","size":3955,"sha":"aece4b700224a0079990b71eaeb4d42b340faaaf","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/recipes/bridge.md"},{"name":"cloudbridge.md","size":2174,"sha":"c1031b1f353f40c4c8e138911d6120b19dd3523b","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/recipes/cloudbridge.md"},{"name":"cloudish.md","size":2084,"sha":"784eb87be552a7a7e46991fae951663600d8082d","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/recipes/cloudish.md"},{"name":"glui.md","size":2069,"sha":"28e753143a749d3065c139d25aef5b2a25404bea","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/recipes/glui.md"},{"name":"hermit.md","size":1955,"sha":"877c0d3455f6ef745fe58513ad33eaa87a1c21ed","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/recipes/hermit.md"},{"name":"lockdown.md","size":1783,"sha":"0114f6efba455aecf7fb7e6b7cb5a951ce81eba4","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/recipes/lockdown.md"},{"name":"multiwin.md","size":1880,"sha":"f6a45dc9818dbb72a186f6de89e503e255cbd609","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/architecture/recipes/multiwin.md"}],"children":[]}]},{"dir":"docs/building","files":[{"name":"app-size.md","size":15914,"sha":"fa96a6fdbf2576fa0686e4ee51b2785ab0932953","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/building/app-size.md"},{"name":"cross-platform.md","size":103,"sha":"fc7ada90f18b51c65b5685a6022c64286bc0662e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/building/cross-platform.md"},{"name":"debian.md","size":1178,"sha":"1d3a20a518ddf9c82eb1fe59d2418dbf4f90e9dc","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/building/debian.md"},{"name":"introduction.md","size":300,"sha":"ba24668c624d14d7af656654fb1b45851cec5a70","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/building/introduction.md"},{"name":"sidecar.md","size":3264,"sha":"d3a25383d9daddf3edb9c879dbdc8bd020ee0def","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/building/sidecar.md"}],"children":[]},{"dir":"docs/community","files":[{"name":"ci-cd.md","size":4659,"sha":"6d213c39bcdb5e5523c48443b5dbee493a295cfb","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/community/ci-cd.md"},{"name":"contributor-guide.md","size":1813,"sha":"f6397d06c792e413cb58a8b80c6459261ee81a14","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/community/contributor-guide.md"}],"children":[]},{"dir":"docs/debugging","files":[{"name":"debugging.md","size":2394,"sha":"981ea4f056ded285ca9000394c2427939bd6f501","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/debugging/debugging.md"}],"children":[]},{"dir":"docs/development","files":[{"name":"development-cycle.md","size":1534,"sha":"9a93dca6cb381bb6dcd3c2a132665b39b342f552","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/development/development-cycle.md"},{"name":"security.md","size":15019,"sha":"1c79d314725abed1a8772dea4501f5266e89356e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/development/security.md"},{"name":"updating-dependencies.md","size":1412,"sha":"cc0e0b7b215803da242d80db787c9f2cffbf7e00","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/development/updating-dependencies.md"}],"children":[]},{"dir":"docs/distribution","files":[{"name":"linux.md","size":2840,"sha":"f686d37b67344085a5650fd4565849729ef69950","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/linux.md"},{"name":"macos.md","size":3733,"sha":"de4ddc8eb721c2e764c65a58d187c9b83a82b69a","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/macos.md"},{"name":"publishing.md","size":965,"sha":"dd6d4848656d27c8f58d93dd4878baadfbb8a0f3","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/publishing.md"},{"name":"sign-macos.md","size":8075,"sha":"020d3561a93d647dbc1596585f0228b4b0e7767f","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/sign-macos.md"},{"name":"sign-windows.md","size":7518,"sha":"d4069b1eaa01784a7a75b8bfb4caf1a2d8a66044","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/sign-windows.md"},{"name":"updater.md","size":10554,"sha":"c931996483c27dd1e8ef3fc4b138e59600c637cf","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/distribution/updater.md"}],"children":[]},{"dir":"docs/getting-started","files":[{"name":"beginning-tutorial.md","size":4608,"sha":"b086ad498c284a5283f11dd24539902c794a8b1c","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/getting-started/beginning-tutorial.md"},{"name":"prerequisites.md","size":708,"sha":"c714cfbe0659f6c8ca47a9f88fd3c0fc911ad37d","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/getting-started/prerequisites.md"},{"name":"setting-up-linux.md","size":5005,"sha":"1357a7e274c997d214cfaea1efb6fde33aad7506","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/getting-started/setting-up-linux.md"},{"name":"setting-up-macos.md","size":2605,"sha":"890590eda522eb050147f0129cb1d42556c82b94","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/getting-started/setting-up-macos.md"},{"name":"setting-up-windows.md","size":3236,"sha":"0482264724ec57e313d38a1713d689ba998163f4","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/getting-started/setting-up-windows.md"}],"children":[]},{"dir":"docs/guides","files":[{"name":"cli.md","size":4607,"sha":"6afeba66519917acc74a5b52bf9a221ea60e667e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/cli.md"},{"name":"command.md","size":6319,"sha":"3b3d643e80285cea010e802df216bf2ac99927f9","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/command.md"},{"name":"events.md","size":4446,"sha":"ed0d6d0e122ba0f1dd11492a5a4c19dcfde9430c","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/events.md"},{"name":"icons.md","size":1326,"sha":"cc42057ce4fa47e3b24a5714045716a3bc1ed8cc","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/icons.md"},{"name":"menu.md","size":4223,"sha":"b82a2dcc83714851d949cfecaf2f9b39c77ae152","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/menu.md"},{"name":"multiwindow.md","size":77,"sha":"46b84b35625fd9c0080acb0b82ef6accf70ab354","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/multiwindow.md"},{"name":"plugin.md","size":5277,"sha":"d51fd656a222afb2b30778ff499c8754dfe73904","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/plugin.md"},{"name":"splashscreen.md","size":3185,"sha":"81d444a73a24d7bcfcfd12071a1c251fa8121ee0","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/splashscreen.md"},{"name":"system-tray.md","size":5050,"sha":"02f29f5985f1914c386714ce8e6e28361c872b71","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/system-tray.md"},{"name":"window-customization.md","size":2363,"sha":"d1a4eed20e2b918865e88530a5ecf4a06bcd341e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/guides/window-customization.md"}],"children":[]},{"dir":"docs/testing","files":[{"name":"mocking.md","size":4100,"sha":"aa5b75dc42cb31280881c205c0e60acd86614a61","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/mocking.md"}],"children":[{"dir":"docs/testing/webdriver","files":[{"name":"ci.md","size":3249,"sha":"214e9c91c106922c414edb0ec630c4b10f76d848","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/webdriver/ci.md"},{"name":"introduction.md","size":2874,"sha":"dc87ecd2de01f2c6357654777cf41a1be0b1e12e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/webdriver/introduction.md"}],"children":[{"dir":"docs/testing/webdriver/example","files":[{"name":"selenium.md","size":7038,"sha":"361973dda3566a035cef36202c7e198dd1934b94","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/webdriver/example/selenium.md"},{"name":"setup.md","size":6694,"sha":"2e0d3471f0f8fc2cf97351df0d891d0fc39ae08d","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/webdriver/example/setup.md"},{"name":"webdriverio.md","size":8233,"sha":"0bfc7b8a9e19e8cbbda638c31942c7ab4b92282e","download_url":"https://raw.githubusercontent.com/tauri-apps/tauri-docs/dev/docs/testing/webdriver/example/webdriverio.md"}],"children":[]}]}]}]} \ No newline at end of file diff --git a/packages/tauri-search/src/mappers/ConsolidatedMapper.ts b/packages/tauri-search/src/mappers/ConsolidatedMapper.ts index 118bd8e..425ca46 100644 --- a/packages/tauri-search/src/mappers/ConsolidatedMapper.ts +++ b/packages/tauri-search/src/mappers/ConsolidatedMapper.ts @@ -1,4 +1,5 @@ -import { ModelMapper, isRepoDocument, isApiDocument, isProseDocument } from "~/types"; +import { ModelMapper, isApiDocument, isProseDocument } from "~/types"; +import {ApiToConsolidated, ProseToConsolidated, RepoToConsolidated} from "./consolidated"; import { IApiModel, IConsolidatedModel, IProseModel, IRepoModel } from "~/models"; export enum IndexRank { @@ -7,82 +8,12 @@ export enum IndexRank { api = 5, } + export const ConsolidatedMapper: ModelMapper< IApiModel | IRepoModel | IProseModel, IConsolidatedModel -> = (i): IConsolidatedModel => ({ - objectID: i.id, - anchor_l2: isProseDocument(i) ? i.headings || null : null, - anchor_l3: isProseDocument(i) ? i.subHeadings || null : null, - area: isProseDocument(i) - ? i.area - : isRepoDocument(i) - ? i.kind - : isApiDocument(i) - ? i.module - : "", - hierarchy_lvl0: isRepoDocument(i) - ? i.name - : isApiDocument(i) - ? i.name || null - : i.title, - hierarchy_lvl1: isRepoDocument(i) - ? i.topics?.join(" ") || null - : isApiDocument(i) - ? i.module || null - : i.tags?.join(" ") || null, - hierarchy_lvl2: isRepoDocument(i) - ? i.kind === "unknown" - ? null - : i.kind || null - : isApiDocument(i) - ? i.language - : i.headings?.join(" ") || null, - hierarchy_lvl3: isRepoDocument(i) - ? i.description || null - : isApiDocument(i) - ? i.module - : i.tags?.join(" ") || null, - hierarchy_lvl4: isRepoDocument(i) - ? i.language || null - : isApiDocument(i) - ? null - : i.section || null, - hierarchy_lvl5: isRepoDocument(i) - ? i.license || null - : isApiDocument(i) - ? null - : i.area || null, - hierarchy_lvl6: isRepoDocument(i) - ? String(i.stars) || null - : isApiDocument(i) - ? null - : i.code?.join(" ") || null, - from: isRepoDocument(i) ? "repo" : isApiDocument(i) ? "api" : "prose", - symbol: isApiDocument(i) ? i.kind : null, - language: isApiDocument(i) - ? i.language - : isRepoDocument(i) - ? i.language - : i.code?.pop() || null, - tags: isRepoDocument(i) ? i.topics || null : isApiDocument(i) ? null : i.tags || null, - content: isRepoDocument(i) - ? i.topics?.join(" ") || null - : isApiDocument(i) - ? i.declaration || null - : i.subHeadings?.join(" ") || null, - - text: isApiDocument(i) ? i.comment || null : i.text || null, - rank: isRepoDocument(i) - ? IndexRank.repo - : isApiDocument(i) - ? IndexRank.api - : IndexRank.prose, - // hierarchy_radio_lvl0: null, - // hierarchy_radio_lvl1: null, - // hierarchy_radio_lvl2: null, - // hierarchy_radio_lvl3: null, - // hierarchy_radio_lvl4: null, - // hierarchy_radio_lvl5: null, - url: i.url, -}); +> = (i) => isApiDocument(i) + ? ApiToConsolidated(i) + : isProseDocument(i) + ? ProseToConsolidated(i) + : RepoToConsolidated(i); diff --git a/packages/tauri-search/src/mappers/consolidated/ApiToConsolidated.ts b/packages/tauri-search/src/mappers/consolidated/ApiToConsolidated.ts new file mode 100644 index 0000000..b86c330 --- /dev/null +++ b/packages/tauri-search/src/mappers/consolidated/ApiToConsolidated.ts @@ -0,0 +1,32 @@ +import { IConsolidatedModel, IApiModel } from "~/models"; +import { ModelMapper } from "~/types"; +import { IndexRank } from "../ConsolidatedMapper"; + +export const ApiToConsolidated: ModelMapper = i => ({ + objectID: i.id, + from: "api", + rank: IndexRank.repo, + + sections: null, + sub_sections: null, + + symbol: i.name, + kind: i.kind, + area: i.module, + language: i.language, + + content: null, + tags: i.tags || [], + text: i.comment || "", + + // compatibility props + hierarchy_lvl0: i.name, + hierarchy_lvl1: i.comment || null, + hierarchy_lvl2: i.declaration || null, + hierarchy_lvl3: null, + hierarchy_lvl4: null, + hierarchy_lvl5: null, + hierarchy_lvl6: null, + + url: i.url +}); \ No newline at end of file diff --git a/packages/tauri-search/src/mappers/consolidated/ProseToConsolidated.ts b/packages/tauri-search/src/mappers/consolidated/ProseToConsolidated.ts new file mode 100644 index 0000000..520eed6 --- /dev/null +++ b/packages/tauri-search/src/mappers/consolidated/ProseToConsolidated.ts @@ -0,0 +1,31 @@ +import { IConsolidatedModel, IProseModel } from "~/models"; +import { ModelMapper } from "~/types"; +import { IndexRank } from "../ConsolidatedMapper"; + +export const ProseToConsolidated: ModelMapper = i => ({ + objectID: i.id, + from: "prose", + rank: IndexRank.prose, + + sections: i.headings || [], + sub_sections: i.subHeadings || [], + + symbol: null, + area: i.area || i.section || null, + language: i.code?.join(" ") || null, + + content: null, + tags: i.tags || [], + text: i.text || "", + + // compatibility props + hierarchy_lvl0: i.title, + hierarchy_lvl1: i.area || null, + hierarchy_lvl2: i.parentSection || null, + hierarchy_lvl3: i.headings?.join(" ") || null, + hierarchy_lvl4: i.text, + hierarchy_lvl5: null, + hierarchy_lvl6: null, + + url: i.url +}); \ No newline at end of file diff --git a/packages/tauri-search/src/mappers/consolidated/RepoToConsolidated.ts b/packages/tauri-search/src/mappers/consolidated/RepoToConsolidated.ts new file mode 100644 index 0000000..25cf206 --- /dev/null +++ b/packages/tauri-search/src/mappers/consolidated/RepoToConsolidated.ts @@ -0,0 +1,32 @@ +import { IConsolidatedModel, IRepoModel } from "~/models"; +import { ModelMapper } from "~/types"; +import { IndexRank } from "../ConsolidatedMapper"; + +export const RepoToConsolidated: ModelMapper = i => ({ + objectID: i.id, + from: "repo", + rank: IndexRank.repo, + + sections: null, + sub_sections: null, + + symbol: null, + area: i.kind === "unknown" ? null : i.kind || null, + language: i.language, + + content: null, + tags: i.topics || [], + text: i.text, + + + // compatibility props + hierarchy_lvl0: i.name, + hierarchy_lvl1: i.description, + hierarchy_lvl2: i.kind === "unknown" ? null : i.kind || null, + hierarchy_lvl3: null, + hierarchy_lvl4: null, + hierarchy_lvl5: null, + hierarchy_lvl6: null, + + url: i.url +}); \ No newline at end of file diff --git a/packages/tauri-search/src/mappers/consolidated/index.ts b/packages/tauri-search/src/mappers/consolidated/index.ts new file mode 100644 index 0000000..e873fd3 --- /dev/null +++ b/packages/tauri-search/src/mappers/consolidated/index.ts @@ -0,0 +1,3 @@ +export * from "./ApiToConsolidated"; +export * from "./ProseToConsolidated"; +export * from "./RepoToConsolidated"; diff --git a/packages/tauri-search/src/models/ConsolidatedModel.ts b/packages/tauri-search/src/models/ConsolidatedModel.ts index 14c95c3..1c7864a 100644 --- a/packages/tauri-search/src/models/ConsolidatedModel.ts +++ b/packages/tauri-search/src/models/ConsolidatedModel.ts @@ -11,14 +11,42 @@ export type IConsolidatedModel = Omit< | "hierarchy_radio_lvl4" | "hierarchy_radio_lvl5" > & { - anchor_l2: string[] | null; - anchor_l3: string[] | null; - area?: string; + /** + * top level sections in a document; in a Markdown doc this + * would typically be an H2 tag + */ + sections: string[] | null; + /** + * a subsection of the document; in a Markdown doc this would + * typically be an H3 tag + */ + sub_sections: string[] | null; + + kind?: string; + + area: string | null; + /** + * The source content/index which this document was derived from + */ from: "prose" | "api" | "repo"; rank: number; + + /** + * most useful for API documents where it has the clearest mapping but + * we can sometimes report on this in other docs too + */ symbol: string | null; + /** + * A great mechanism for content authors to add words that should + * be associated with the document in markdown (as frontmatter). + * In repo's we can also add topics of the repo into this property. + */ tags: null | string[]; + /** + * allows association of content to a particular programming language + */ language: string | null; + /** the main body of text */ text: string | null; }; @@ -31,20 +59,24 @@ export const ConsolidatedModel = createModel("consolidated", js: ["typescript", "javascript", "js"], typescript: ["ts", "javascript", "js"], javascript: ["ts", "typescript", "js"], + }) .filterable("from", "language", "symbol") .searchable( "area", + "symbol", + "tags", "hierarchy_lvl0", "hierarchy_lvl1", - "anchor_l2", - "symbol", + "sections", "rank", - "tags", - "content", "hierarchy_lvl2", "hierarchy_lvl3", - "anchor_l3" + "hierarchy_lvl4", + "hierarchy_lvl5", + "text", + "kind", + "sub_sections" ) .rankingRules((r) => r.words().typo().sort().attribute().proximity().ASC("rank").exactness() diff --git a/packages/tauri-search/test/ast/parseRust.test.ts b/packages/tauri-search/test/ast/parseRust.test.ts index 917b100..c6f506d 100644 --- a/packages/tauri-search/test/ast/parseRust.test.ts +++ b/packages/tauri-search/test/ast/parseRust.test.ts @@ -1,5 +1,29 @@ +import { readFile } from "fs/promises"; +import { beforeAll } from "vitest"; import { describe, expect, it } from "vitest"; +import { RUST_AST_FIXTURE } from "~/constants"; -describe("rustParser() - AST to List", () => { - it.todo("first test", () => {}); +export interface IRustAst { + root: string; + /** semver string */ + crate_version: string; + includes_private: boolean; + index: any; + paths: any; + external_crates: any; + format_version: number; +} + +describe("parseRustAst()", () => { + let ast: IRustAst; + beforeAll(async () => { + ast = JSON.parse(await readFile(RUST_AST_FIXTURE, "utf-8")) as IRustAst; + }); + it("loaded fixture structure", () => { + expect(typeof ast.format_version).toEqual("number"); + + // crate_version is a semver string + expect(typeof ast.crate_version).toEqual("string"); + expect(ast.crate_version.split(".")).toHaveLength(3); + }); }); diff --git a/packages/tauri-search/test/ast/parseTypescript.test.ts b/packages/tauri-search/test/ast/parseTypescript.test.ts index e58b78d..45ea423 100644 --- a/packages/tauri-search/test/ast/parseTypescript.test.ts +++ b/packages/tauri-search/test/ast/parseTypescript.test.ts @@ -4,7 +4,7 @@ import { TypescriptKind } from "~/enums"; import type { Expect, Equal } from "@type-challenges/utils"; import { TsDocProject, TypescriptBlock, TypescriptSymbol } from "~/types"; import { getRepoFile } from "~/utils/github/getRepoFile"; -import { getEnv } from "~/utils/getEnv"; +import { getEnv } from "~/utils/getEnv/esm/getEnv"; let prj: TsDocProject; diff --git a/packages/tauri-search/test/fixtures/rust-docs.json b/packages/tauri-search/test/fixtures/rust-ast.json similarity index 100% rename from packages/tauri-search/test/fixtures/rust-docs.json rename to packages/tauri-search/test/fixtures/rust-ast.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8a50330..fd3f671 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: packages/docs: specifiers: '@antfu/eslint-config': ^0.16.1 - '@iconify/json': ^2.0.35 + '@iconify/json': ^2.0.36 '@intlify/vite-plugin-vue-i18n': ^3.2.2 '@types/markdown-it-link-attributes': ^3.0.1 '@types/nprogress': ^0.2.0 @@ -28,7 +28,7 @@ importers: date-fns: ^2.28.0 docs-searchbar.js: ^2.1.0 dotenv: ^16.0.0 - eslint: ^8.8.0 + eslint: ^8.9.0 eslint-plugin-cypress: ^2.12.1 floating-vue: ^2.0.0-beta.6 https-localhost: ^4.7.0 @@ -38,6 +38,7 @@ importers: markdown-it-expandable: ^1.0.2 markdown-it-link-attributes: ^4.0.0 markdown-it-prism: ^2.2.2 + meili-searchbar: ^2.2.1 nprogress: ^0.2.0 pinia: ^2.0.11 prism-theme-vars: ^0.2.2 @@ -46,15 +47,15 @@ importers: unplugin-auto-import: ^0.5.11 unplugin-icons: ^0.13.1 unplugin-vue-components: ^0.17.18 - vite: ^2.8.0 - vite-plugin-inspect: ^0.3.13 + vite: ^2.8.1 + vite-plugin-inspect: ^0.3.14 vite-plugin-md: ^0.11.8 vite-plugin-pages: ^0.20.2 vite-plugin-pwa: ^0.11.13 vite-plugin-vue-layouts: ^0.6.0 vite-plugin-windicss: ^1.7.0 vite-ssg: ^0.17.10 - vitest: ^0.3.0 + vitest: ^0.3.2 vue: ^3.2.30 vue-demi: ^0.12.1 vue-i18n: ^9.1.9 @@ -77,38 +78,39 @@ importers: vue-i18n: 9.1.9_vue@3.2.30 vue-router: 4.0.12_vue@3.2.30 devDependencies: - '@antfu/eslint-config': 0.16.1_eslint@8.8.0+typescript@4.5.5 - '@iconify/json': 2.0.35 - '@intlify/vite-plugin-vue-i18n': 3.2.2_vite@2.8.0+vue-i18n@9.1.9 + '@antfu/eslint-config': 0.16.1_eslint@8.9.0+typescript@4.5.5 + '@iconify/json': 2.0.36 + '@intlify/vite-plugin-vue-i18n': 3.2.2_vite@2.8.1+vue-i18n@9.1.9 '@types/markdown-it-link-attributes': 3.0.1 '@types/nprogress': 0.2.0 - '@vitejs/plugin-vue': 2.2.0_vite@2.8.0+vue@3.2.30 + '@vitejs/plugin-vue': 2.2.0_vite@2.8.1+vue@3.2.30 '@vue/compiler-sfc': 3.2.30 '@vue/server-renderer': 3.2.30_vue@3.2.30 '@vue/test-utils': 2.0.0-rc.18_vue@3.2.30 critters: 0.0.16 cross-env: 7.0.3 dotenv: 16.0.0 - eslint: 8.8.0 - eslint-plugin-cypress: 2.12.1_eslint@8.8.0 + eslint: 8.9.0 + eslint-plugin-cypress: 2.12.1_eslint@8.9.0 https-localhost: 4.7.0 jsdom: 19.0.0 markdown-it: 12.3.2 markdown-it-link-attributes: 4.0.0 markdown-it-prism: 2.2.2 + meili-searchbar: 2.2.1_vue@3.2.30 typescript: 4.5.5 - unplugin-auto-import: 0.5.11_@vueuse+core@7.6.1+vite@2.8.0 - unplugin-icons: 0.13.1_74c57c6669a9652c267f522b0d6c9a3b - unplugin-vue-components: 0.17.18_vite@2.8.0+vue@3.2.30 - vite: 2.8.0 - vite-plugin-inspect: 0.3.13_vite@2.8.0 - vite-plugin-md: 0.11.8_vite@2.8.0 - vite-plugin-pages: 0.20.2_74c57c6669a9652c267f522b0d6c9a3b - vite-plugin-pwa: 0.11.13_vite@2.8.0 - vite-plugin-vue-layouts: 0.6.0_96c99e3b7a55d9fa64f74317a359b00e - vite-plugin-windicss: 1.7.0_vite@2.8.0 - vite-ssg: 0.17.10_dd02a634c6d9f894c7a4243a6abbc11a - vitest: 0.3.0_jsdom@19.0.0 + unplugin-auto-import: 0.5.11_@vueuse+core@7.6.1+vite@2.8.1 + unplugin-icons: 0.13.1_f38b2674125d22360785c84d0f6f797d + unplugin-vue-components: 0.17.18_vite@2.8.1+vue@3.2.30 + vite: 2.8.1 + vite-plugin-inspect: 0.3.14_vite@2.8.1 + vite-plugin-md: 0.11.8_vite@2.8.1 + vite-plugin-pages: 0.20.2_f38b2674125d22360785c84d0f6f797d + vite-plugin-pwa: 0.11.13_vite@2.8.1 + vite-plugin-vue-layouts: 0.6.0_861efee176eccc75a49e11466b75d03a + vite-plugin-windicss: 1.7.0_vite@2.8.1 + vite-ssg: 0.17.10_2a1f4eb68d7efe0f1402d91afc414ace + vitest: 0.3.2_jsdom@19.0.0 vue-tsc: 0.31.2_typescript@4.5.5 packages/tauri-search: @@ -117,14 +119,14 @@ importers: '@type-challenges/utils': ^0.1.1 '@types/html-to-text': ^8.0.1 '@types/markdown-it': ^12.2.3 - '@types/node': ^14.18.10 - '@typescript-eslint/eslint-plugin': ^5.11.0 - '@typescript-eslint/parser': ^5.11.0 - '@vitest/ui': ^0.3.0 + '@types/node': ^14.18.12 + '@typescript-eslint/eslint-plugin': ^5.12.0 + '@typescript-eslint/parser': ^5.12.0 + '@vitest/ui': ^0.3.5 axios: ^0.25.0 changeset: ^0.2.6 dotenv: ^16.0.0 - eslint: ^8.8.0 + eslint: ^8.9.0 eslint-config-prettier: ^8.3.0 eslint-plugin-cypress: ^2.12.1 eslint-plugin-import: ^2.25.4 @@ -136,7 +138,7 @@ importers: html-to-text: ^8.1.0 husky: ^7.0.4 inferred-types: ^0.18.4 - native-dash: ^1.21.5 + native-dash: ^1.22.0 npm-run-all: ^4.1.5 prettier: ^2.5.1 rimraf: ^3.0.2 @@ -144,10 +146,10 @@ importers: ts-node: ^10.5.0 tsup: ^5.11.13 typescript: ^4.5.5 - vite: ^2.8.0 + vite: ^2.8.2 vite-plugin-dts: ^0.9.9 - vite-plugin-inspect: ^0.3.13 - vitest: ^0.3.0 + vite-plugin-inspect: ^0.3.14 + vitest: ^0.3.5 dependencies: '@types/html-to-text': 8.0.1 axios: 0.25.0 @@ -156,127 +158,127 @@ importers: gray-matter: 4.0.3 html-to-text: 8.1.0 inferred-types: 0.18.4 - native-dash: 1.21.5 + native-dash: 1.22.0 simple-markdown-2: 0.7.5 devDependencies: '@octokit/types': 6.34.0 '@type-challenges/utils': 0.1.1 '@types/markdown-it': 12.2.3 - '@types/node': 14.18.10 - '@typescript-eslint/eslint-plugin': 5.11.0_de5a1ddccd75ca1e499b8b8491d3dcba - '@typescript-eslint/parser': 5.11.0_eslint@8.8.0+typescript@4.5.5 - '@vitest/ui': 0.3.0 + '@types/node': 14.18.12 + '@typescript-eslint/eslint-plugin': 5.12.0_c467cf9bb49b295941e83ce479a578b7 + '@typescript-eslint/parser': 5.12.0_eslint@8.9.0+typescript@4.5.5 + '@vitest/ui': 0.3.5 changeset: 0.2.6 - eslint: 8.8.0 - eslint-config-prettier: 8.3.0_eslint@8.8.0 - eslint-plugin-cypress: 2.12.1_eslint@8.8.0 - eslint-plugin-import: 2.25.4_eslint@8.8.0 - eslint-plugin-prettier: 4.0.0_43197c8d12d1d439034cfcf65e1c48c2 - eslint-plugin-promise: 6.0.0_eslint@8.8.0 + eslint: 8.9.0 + eslint-config-prettier: 8.3.0_eslint@8.9.0 + eslint-plugin-cypress: 2.12.1_eslint@8.9.0 + eslint-plugin-import: 2.25.4_eslint@8.9.0 + eslint-plugin-prettier: 4.0.0_07b422646bb75d3db791621d4fdbc992 + eslint-plugin-promise: 6.0.0_eslint@8.9.0 fx: 20.0.2 husky: 7.0.4 npm-run-all: 4.1.5 prettier: 2.5.1 rimraf: 3.0.2 - ts-node: 10.5.0_d9704c9be36ede869b5c33ef6688872e + ts-node: 10.5.0_31a32bd81d8bbfc3c2c321de918dd405 tsup: 5.11.13_ts-node@10.5.0+typescript@4.5.5 typescript: 4.5.5 - vite: 2.8.0 - vite-plugin-dts: 0.9.9_vite@2.8.0 - vite-plugin-inspect: 0.3.13_vite@2.8.0 - vitest: 0.3.0_@vitest+ui@0.3.0 + vite: 2.8.2 + vite-plugin-dts: 0.9.9_vite@2.8.2 + vite-plugin-inspect: 0.3.14_vite@2.8.2 + vitest: 0.3.5_@vitest+ui@0.3.5 packages: - /@ampproject/remapping/2.1.0: - resolution: {integrity: sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g==} + /@ampproject/remapping/2.1.1: + resolution: {integrity: sha512-Aolwjd7HSC2PyY0fDj/wA/EimQT4HfEnFYNp5s9CQlrdhyvWTtvZ5YzrUPu6R6/1jKiUlxu8bUhkdSnKHNAHMA==} engines: {node: '>=6.0.0'} dependencies: '@jridgewell/trace-mapping': 0.3.4 dev: true - /@antfu/eslint-config-basic/0.16.1_eslint@8.8.0: + /@antfu/eslint-config-basic/0.16.1_eslint@8.9.0: resolution: {integrity: sha512-kUA7UBD1W8FG2frH4pKfos4l5eUSxVH8oMK7+T9OxBAxpvXDAYUGU0KNZoMOdhWhu0dmE/7iHXYbnu6r9KXwUw==} peerDependencies: eslint: '>=7.4.0' dependencies: - eslint: 8.8.0 - eslint-config-standard: 17.0.0-0_d98185a972f50d26baaf376f983a6b27 - eslint-plugin-eslint-comments: 3.2.0_eslint@8.8.0 + eslint: 8.9.0 + eslint-config-standard: 17.0.0-0_c8ad1c911fa160b4a9904c4bb416080e + eslint-plugin-eslint-comments: 3.2.0_eslint@8.9.0 eslint-plugin-html: 6.2.0 - eslint-plugin-import: 2.25.4_eslint@8.8.0 - eslint-plugin-jsonc: 2.1.0_eslint@8.8.0 - eslint-plugin-n: 14.0.0_eslint@8.8.0 - eslint-plugin-promise: 6.0.0_eslint@8.8.0 - eslint-plugin-unicorn: 40.1.0_eslint@8.8.0 - eslint-plugin-yml: 0.12.0_eslint@8.8.0 + eslint-plugin-import: 2.25.4_eslint@8.9.0 + eslint-plugin-jsonc: 2.1.0_eslint@8.9.0 + eslint-plugin-n: 14.0.0_eslint@8.9.0 + eslint-plugin-promise: 6.0.0_eslint@8.9.0 + eslint-plugin-unicorn: 40.1.0_eslint@8.9.0 + eslint-plugin-yml: 0.12.0_eslint@8.9.0 jsonc-eslint-parser: 2.1.0 yaml-eslint-parser: 0.5.0 transitivePeerDependencies: - supports-color dev: true - /@antfu/eslint-config-react/0.16.1_eslint@8.8.0+typescript@4.5.5: + /@antfu/eslint-config-react/0.16.1_eslint@8.9.0+typescript@4.5.5: resolution: {integrity: sha512-UU/KqDVRb6/XQVBsrL2a3fBwn2NRGWnZCBPAU9HbIqLY/zJ5p8CpBJTvvIvCC4p4aiO3unwnYhhf5SdCQtfOjw==} peerDependencies: eslint: '>=7.4.0' dependencies: - '@antfu/eslint-config-ts': 0.16.1_eslint@8.8.0+typescript@4.5.5 - eslint: 8.8.0 - eslint-plugin-react: 7.28.0_eslint@8.8.0 + '@antfu/eslint-config-ts': 0.16.1_eslint@8.9.0+typescript@4.5.5 + eslint: 8.9.0 + eslint-plugin-react: 7.28.0_eslint@8.9.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@antfu/eslint-config-ts/0.16.1_eslint@8.8.0+typescript@4.5.5: + /@antfu/eslint-config-ts/0.16.1_eslint@8.9.0+typescript@4.5.5: resolution: {integrity: sha512-FrIosrYILXog7v8GcQkj8YyMKe6HxUvv8DFDHxQjR5liI77BQ9kmIqRu8JZ/6RwMEEpMWV5Ed+LDR7FDjJiTxg==} peerDependencies: eslint: '>=7.4.0' typescript: '>=3.9' dependencies: - '@antfu/eslint-config-basic': 0.16.1_eslint@8.8.0 - '@typescript-eslint/eslint-plugin': 5.11.0_de5a1ddccd75ca1e499b8b8491d3dcba - '@typescript-eslint/parser': 5.11.0_eslint@8.8.0+typescript@4.5.5 - eslint: 8.8.0 + '@antfu/eslint-config-basic': 0.16.1_eslint@8.9.0 + '@typescript-eslint/eslint-plugin': 5.11.0_15a231715447500ed5c06da64c8aef1c + '@typescript-eslint/parser': 5.11.0_eslint@8.9.0+typescript@4.5.5 + eslint: 8.9.0 typescript: 4.5.5 transitivePeerDependencies: - supports-color dev: true - /@antfu/eslint-config-vue/0.16.1_eslint@8.8.0+typescript@4.5.5: + /@antfu/eslint-config-vue/0.16.1_eslint@8.9.0+typescript@4.5.5: resolution: {integrity: sha512-2BMQBTVQrElu2Pvmubgc1G3BrCbaQjBzcepZZvHNnK74Wq4ec1Cl5i9BMRVVwBGg5fIg5erRPzUWr17j5BLa0A==} peerDependencies: eslint: '>=7.4.0' dependencies: - '@antfu/eslint-config-ts': 0.16.1_eslint@8.8.0+typescript@4.5.5 - eslint: 8.8.0 - eslint-plugin-vue: 8.4.1_eslint@8.8.0 + '@antfu/eslint-config-ts': 0.16.1_eslint@8.9.0+typescript@4.5.5 + eslint: 8.9.0 + eslint-plugin-vue: 8.4.1_eslint@8.9.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@antfu/eslint-config/0.16.1_eslint@8.8.0+typescript@4.5.5: + /@antfu/eslint-config/0.16.1_eslint@8.9.0+typescript@4.5.5: resolution: {integrity: sha512-GYJMtcEpHNNQA1A2acsRqSKGRkLEZ38Y9lvHBcX7HomJ+NsPFG4a3AJ5DW1CKpPTk5W3mOF0XBMiGA+pQOC37g==} peerDependencies: eslint: '>=7.4.0' dependencies: - '@antfu/eslint-config-react': 0.16.1_eslint@8.8.0+typescript@4.5.5 - '@antfu/eslint-config-vue': 0.16.1_eslint@8.8.0+typescript@4.5.5 - '@typescript-eslint/eslint-plugin': 5.11.0_de5a1ddccd75ca1e499b8b8491d3dcba - '@typescript-eslint/parser': 5.11.0_eslint@8.8.0+typescript@4.5.5 - eslint: 8.8.0 - eslint-config-standard: 17.0.0-0_d98185a972f50d26baaf376f983a6b27 - eslint-plugin-eslint-comments: 3.2.0_eslint@8.8.0 + '@antfu/eslint-config-react': 0.16.1_eslint@8.9.0+typescript@4.5.5 + '@antfu/eslint-config-vue': 0.16.1_eslint@8.9.0+typescript@4.5.5 + '@typescript-eslint/eslint-plugin': 5.11.0_15a231715447500ed5c06da64c8aef1c + '@typescript-eslint/parser': 5.11.0_eslint@8.9.0+typescript@4.5.5 + eslint: 8.9.0 + eslint-config-standard: 17.0.0-0_c8ad1c911fa160b4a9904c4bb416080e + eslint-plugin-eslint-comments: 3.2.0_eslint@8.9.0 eslint-plugin-html: 6.2.0 - eslint-plugin-import: 2.25.4_eslint@8.8.0 - eslint-plugin-jsonc: 2.1.0_eslint@8.8.0 - eslint-plugin-n: 14.0.0_eslint@8.8.0 - eslint-plugin-promise: 6.0.0_eslint@8.8.0 - eslint-plugin-unicorn: 40.1.0_eslint@8.8.0 - eslint-plugin-vue: 8.4.1_eslint@8.8.0 - eslint-plugin-yml: 0.12.0_eslint@8.8.0 + eslint-plugin-import: 2.25.4_eslint@8.9.0 + eslint-plugin-jsonc: 2.1.0_eslint@8.9.0 + eslint-plugin-n: 14.0.0_eslint@8.9.0 + eslint-plugin-promise: 6.0.0_eslint@8.9.0 + eslint-plugin-unicorn: 40.1.0_eslint@8.9.0 + eslint-plugin-vue: 8.4.1_eslint@8.9.0 + eslint-plugin-yml: 0.12.0_eslint@8.9.0 jsonc-eslint-parser: 2.1.0 yaml-eslint-parser: 0.5.0 transitivePeerDependencies: @@ -335,7 +337,7 @@ packages: resolution: {integrity: sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==} engines: {node: '>=6.9.0'} dependencies: - '@ampproject/remapping': 2.1.0 + '@ampproject/remapping': 2.1.1 '@babel/code-frame': 7.16.7 '@babel/generator': 7.17.0 '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.2 @@ -1455,8 +1457,8 @@ packages: '@cspotcode/source-map-consumer': 0.8.0 dev: true - /@emmetio/abbreviation/2.2.2: - resolution: {integrity: sha512-TtE/dBnkTCct8+LntkqVrwqQao6EnPAs1YN3cUgxOxTaBlesBCY37ROUAVZrRlG64GNnVShdl/b70RfAI3w5lw==} + /@emmetio/abbreviation/2.2.3: + resolution: {integrity: sha512-87pltuCPt99aL+y9xS6GPZ+Wmmyhll2WXH73gG/xpGcQ84DRnptBsI2r0BeIQ0EB/SQTOe2ANPqFqj3Rj5FOGA==} dependencies: '@emmetio/scanner': 1.0.0 dev: true @@ -1471,18 +1473,18 @@ packages: resolution: {integrity: sha512-8HqW8EVqjnCmWXVpqAOZf+EGESdkR27odcMMMGefgKXtar00SoYNSryGv//TELI4T3QFsECo78p+0lmalk/CFA==} dev: true - /@eslint/eslintrc/1.0.5: - resolution: {integrity: sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==} + /@eslint/eslintrc/1.1.0: + resolution: {integrity: sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.3 - espree: 9.3.0 + espree: 9.3.1 globals: 13.12.1 ignore: 4.0.6 import-fresh: 3.3.0 js-yaml: 4.1.0 - minimatch: 3.0.5 + minimatch: 3.1.1 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color @@ -1490,13 +1492,11 @@ packages: /@floating-ui/core/0.3.1: resolution: {integrity: sha512-ensKY7Ub59u16qsVIFEo2hwTCqZ/r9oZZFh51ivcLGHfUwTn8l1Xzng8RJUe91H/UP8PeqeBronAGx0qmzwk2g==} - dev: false /@floating-ui/dom/0.1.10: resolution: {integrity: sha512-4kAVoogvQm2N0XE0G6APQJuCNuErjOfPW8Ux7DFxh8+AfugWflwVJ5LDlHOwrwut7z/30NUvdtHzQ3zSip4EzQ==} dependencies: '@floating-ui/core': 0.3.1 - dev: false /@humanwhocodes/config-array/0.9.3: resolution: {integrity: sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==} @@ -1504,7 +1504,7 @@ packages: dependencies: '@humanwhocodes/object-schema': 1.2.1 debug: 4.3.3 - minimatch: 3.0.5 + minimatch: 3.1.1 transitivePeerDependencies: - supports-color dev: true @@ -1513,8 +1513,8 @@ packages: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true - /@iconify/json/2.0.35: - resolution: {integrity: sha512-bpXaOEWTr4ngifLO9eOp6gOSPSqEqKHGLQLDVzTmGJuGROx6dJNm/29EKYsKdzrcz6JpyUxZRbI4qzn4tdr9wQ==} + /@iconify/json/2.0.36: + resolution: {integrity: sha512-IOFRnVwo7Nf3Xyzm1pExDqp9cygoWjouAsn0IpFuaPO9dDyh7SaVjnxvfB9+nk8y/o8N8nXCnvk4dgyA+dB+qA==} dependencies: '@iconify/types': 1.0.12 pathe: 0.0.2 @@ -1617,7 +1617,7 @@ packages: engines: {node: '>= 12'} dev: true - /@intlify/vite-plugin-vue-i18n/3.2.2_vite@2.8.0+vue-i18n@9.1.9: + /@intlify/vite-plugin-vue-i18n/3.2.2_vite@2.8.1+vue-i18n@9.1.9: resolution: {integrity: sha512-d5SCEVanpF8yJFI15q6Q1vXB0t+pChSkbD3riT+/ih4LXqY8ZsUim053f4auhToj40wwVtF/9Fa9zioQbQGQbA==} engines: {node: '>= 12'} peerDependencies: @@ -1636,7 +1636,7 @@ packages: debug: 4.3.3 fast-glob: 3.2.11 source-map: 0.6.1 - vite: 2.8.0 + vite: 2.8.1 vue-i18n: 9.1.9_vue@3.2.30 transitivePeerDependencies: - supports-color @@ -1651,20 +1651,20 @@ packages: '@intlify/shared': 9.1.9 dev: false - /@jridgewell/resolve-uri/3.0.4: - resolution: {integrity: sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==} + /@jridgewell/resolve-uri/3.0.5: + resolution: {integrity: sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==} engines: {node: '>=6.0.0'} dev: true - /@jridgewell/sourcemap-codec/1.4.10: - resolution: {integrity: sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==} + /@jridgewell/sourcemap-codec/1.4.11: + resolution: {integrity: sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==} dev: true /@jridgewell/trace-mapping/0.3.4: resolution: {integrity: sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==} dependencies: - '@jridgewell/resolve-uri': 3.0.4 - '@jridgewell/sourcemap-codec': 1.4.10 + '@jridgewell/resolve-uri': 3.0.5 + '@jridgewell/sourcemap-codec': 1.4.11 dev: true /@medv/blessed/2.0.1: @@ -1705,7 +1705,7 @@ packages: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} dev: true - /@rollup/plugin-babel/5.3.0_@babel+core@7.17.2+rollup@2.67.1: + /@rollup/plugin-babel/5.3.0_@babel+core@7.17.2+rollup@2.67.2: resolution: {integrity: sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==} engines: {node: '>= 10.0.0'} peerDependencies: @@ -1718,36 +1718,36 @@ packages: dependencies: '@babel/core': 7.17.2 '@babel/helper-module-imports': 7.16.7 - '@rollup/pluginutils': 3.1.0_rollup@2.67.1 - rollup: 2.67.1 + '@rollup/pluginutils': 3.1.0_rollup@2.67.2 + rollup: 2.67.2 dev: true - /@rollup/plugin-node-resolve/11.2.1_rollup@2.67.1: + /@rollup/plugin-node-resolve/11.2.1_rollup@2.67.2: resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} engines: {node: '>= 10.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0 dependencies: - '@rollup/pluginutils': 3.1.0_rollup@2.67.1 + '@rollup/pluginutils': 3.1.0_rollup@2.67.2 '@types/resolve': 1.17.1 builtin-modules: 3.2.0 deepmerge: 4.2.2 is-module: 1.0.0 resolve: 1.22.0 - rollup: 2.67.1 + rollup: 2.67.2 dev: true - /@rollup/plugin-replace/2.4.2_rollup@2.67.1: + /@rollup/plugin-replace/2.4.2_rollup@2.67.2: resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} peerDependencies: rollup: ^1.20.0 || ^2.0.0 dependencies: - '@rollup/pluginutils': 3.1.0_rollup@2.67.1 + '@rollup/pluginutils': 3.1.0_rollup@2.67.2 magic-string: 0.25.7 - rollup: 2.67.1 + rollup: 2.67.2 dev: true - /@rollup/pluginutils/3.1.0_rollup@2.67.1: + /@rollup/pluginutils/3.1.0_rollup@2.67.2: resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} engines: {node: '>= 8.0.0'} peerDependencies: @@ -1756,7 +1756,7 @@ packages: '@types/estree': 0.0.39 estree-walker: 1.0.1 picomatch: 2.3.1 - rollup: 2.67.1 + rollup: 2.67.2 dev: true /@rollup/pluginutils/4.1.2: @@ -1792,7 +1792,7 @@ packages: resolution: {integrity: sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w==} dependencies: fast-glob: 3.2.11 - minimatch: 3.0.5 + minimatch: 3.1.1 mkdirp: 1.0.4 path-browserify: 1.0.1 dev: true @@ -1864,12 +1864,12 @@ packages: resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} dev: true - /@types/node/14.18.10: - resolution: {integrity: sha512-6iihJ/Pp5fsFJ/aEDGyvT4pHGmCpq7ToQ/yf4bl5SbVAvwpspYJ+v3jO7n8UyjhQVHTy+KNszOozDdv+O6sovQ==} + /@types/node/14.18.12: + resolution: {integrity: sha512-q4jlIR71hUpWTnGhXWcakgkZeHa3CCjcQcnuzU8M891BAWA2jHiziiWEPEkdS5pFsz7H9HJiy8BrK7tBRNrY7A==} dev: true - /@types/node/17.0.16: - resolution: {integrity: sha512-ydLaGVfQOQ6hI1xK2A5nVh8bl0OGoIfYMxPWHqqYe9bTkWCfqiVvZoh2I/QF2sNSkZzZyROBoTefIEI+PB6iIA==} + /@types/node/17.0.17: + resolution: {integrity: sha512-e8PUNQy1HgJGV3iU/Bp2+D/DXh3PYeyli8LgIwsQcs1Ar1LoaWHSIT6Rw+H2rNJmiq6SNWiDytfx8+gYj7wDHw==} dev: true /@types/normalize-package-data/2.4.1: @@ -1883,7 +1883,7 @@ packages: /@types/resolve/1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} dependencies: - '@types/node': 17.0.16 + '@types/node': 17.0.17 dev: true /@types/throttle-debounce/2.1.0: @@ -1894,7 +1894,7 @@ packages: resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==} dev: true - /@typescript-eslint/eslint-plugin/5.11.0_de5a1ddccd75ca1e499b8b8491d3dcba: + /@typescript-eslint/eslint-plugin/5.11.0_15a231715447500ed5c06da64c8aef1c: resolution: {integrity: sha512-HJh33bgzXe6jGRocOj4FmefD7hRY4itgjzOrSs3JPrTNXsX7j5+nQPciAUj/1nZtwo2kAc3C75jZO+T23gzSGw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1905,12 +1905,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.11.0_eslint@8.8.0+typescript@4.5.5 + '@typescript-eslint/parser': 5.11.0_eslint@8.9.0+typescript@4.5.5 '@typescript-eslint/scope-manager': 5.11.0 - '@typescript-eslint/type-utils': 5.11.0_eslint@8.8.0+typescript@4.5.5 - '@typescript-eslint/utils': 5.11.0_eslint@8.8.0+typescript@4.5.5 + '@typescript-eslint/type-utils': 5.11.0_eslint@8.9.0+typescript@4.5.5 + '@typescript-eslint/utils': 5.11.0_eslint@8.9.0+typescript@4.5.5 debug: 4.3.3 - eslint: 8.8.0 + eslint: 8.9.0 functional-red-black-tree: 1.0.1 ignore: 5.2.0 regexpp: 3.2.0 @@ -1921,7 +1921,34 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.11.0_eslint@8.8.0+typescript@4.5.5: + /@typescript-eslint/eslint-plugin/5.12.0_c467cf9bb49b295941e83ce479a578b7: + resolution: {integrity: sha512-fwCMkDimwHVeIOKeBHiZhRUfJXU8n6xW1FL9diDxAyGAFvKcH4csy0v7twivOQdQdA0KC8TDr7GGRd3L4Lv0rQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/parser': 5.12.0_eslint@8.9.0+typescript@4.5.5 + '@typescript-eslint/scope-manager': 5.12.0 + '@typescript-eslint/type-utils': 5.12.0_eslint@8.9.0+typescript@4.5.5 + '@typescript-eslint/utils': 5.12.0_eslint@8.9.0+typescript@4.5.5 + debug: 4.3.3 + eslint: 8.9.0 + functional-red-black-tree: 1.0.1 + ignore: 5.2.0 + regexpp: 3.2.0 + semver: 7.3.5 + tsutils: 3.21.0_typescript@4.5.5 + typescript: 4.5.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser/5.11.0_eslint@8.9.0+typescript@4.5.5: resolution: {integrity: sha512-x0DCjetHZYBRovJdr3U0zG9OOdNXUaFLJ82ehr1AlkArljJuwEsgnud+Q7umlGDFLFrs8tU8ybQDFocp/eX8mQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1935,7 +1962,27 @@ packages: '@typescript-eslint/types': 5.11.0 '@typescript-eslint/typescript-estree': 5.11.0_typescript@4.5.5 debug: 4.3.3 - eslint: 8.8.0 + eslint: 8.9.0 + typescript: 4.5.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser/5.12.0_eslint@8.9.0+typescript@4.5.5: + resolution: {integrity: sha512-MfSwg9JMBojMUoGjUmX+D2stoQj1CBYTCP0qnnVtu9A+YQXVKNtLjasYh+jozOcrb/wau8TCfWOkQTiOAruBog==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.12.0 + '@typescript-eslint/types': 5.12.0 + '@typescript-eslint/typescript-estree': 5.12.0_typescript@4.5.5 + debug: 4.3.3 + eslint: 8.9.0 typescript: 4.5.5 transitivePeerDependencies: - supports-color @@ -1949,7 +1996,15 @@ packages: '@typescript-eslint/visitor-keys': 5.11.0 dev: true - /@typescript-eslint/type-utils/5.11.0_eslint@8.8.0+typescript@4.5.5: + /@typescript-eslint/scope-manager/5.12.0: + resolution: {integrity: sha512-GAMobtIJI8FGf1sLlUWNUm2IOkIjvn7laFWyRx7CLrv6nLBI7su+B7lbStqVlK5NdLvHRFiJo2HhiDF7Ki01WQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.12.0 + '@typescript-eslint/visitor-keys': 5.12.0 + dev: true + + /@typescript-eslint/type-utils/5.11.0_eslint@8.9.0+typescript@4.5.5: resolution: {integrity: sha512-wDqdsYO6ofLaD4DsGZ0jGwxp4HrzD2YKulpEZXmgN3xo4BHJwf7kq49JTRpV0Gx6bxkSUmc9s0EIK1xPbFFpIA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1959,9 +2014,28 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/utils': 5.11.0_eslint@8.8.0+typescript@4.5.5 + '@typescript-eslint/utils': 5.11.0_eslint@8.9.0+typescript@4.5.5 debug: 4.3.3 - eslint: 8.8.0 + eslint: 8.9.0 + tsutils: 3.21.0_typescript@4.5.5 + typescript: 4.5.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/type-utils/5.12.0_eslint@8.9.0+typescript@4.5.5: + resolution: {integrity: sha512-9j9rli3zEBV+ae7rlbBOotJcI6zfc6SHFMdKI9M3Nc0sy458LJ79Os+TPWeBBL96J9/e36rdJOfCuyRSgFAA0Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/utils': 5.12.0_eslint@8.9.0+typescript@4.5.5 + debug: 4.3.3 + eslint: 8.9.0 tsutils: 3.21.0_typescript@4.5.5 typescript: 4.5.5 transitivePeerDependencies: @@ -1973,6 +2047,11 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@typescript-eslint/types/5.12.0: + resolution: {integrity: sha512-JowqbwPf93nvf8fZn5XrPGFBdIK8+yx5UEGs2QFAYFI8IWYfrzz+6zqlurGr2ctShMaJxqwsqmra3WXWjH1nRQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /@typescript-eslint/typescript-estree/5.11.0_typescript@4.5.5: resolution: {integrity: sha512-yVH9hKIv3ZN3lw8m/Jy5I4oXO4ZBMqijcXCdA4mY8ull6TPTAoQnKKrcZ0HDXg7Bsl0Unwwx7jcXMuNZc0m4lg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1994,7 +2073,28 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.11.0_eslint@8.8.0+typescript@4.5.5: + /@typescript-eslint/typescript-estree/5.12.0_typescript@4.5.5: + resolution: {integrity: sha512-Dd9gVeOqt38QHR0BEA8oRaT65WYqPYbIc5tRFQPkfLquVEFPD1HAtbZT98TLBkEcCkvwDYOAvuSvAD9DnQhMfQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.12.0 + '@typescript-eslint/visitor-keys': 5.12.0 + debug: 4.3.3 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.5 + tsutils: 3.21.0_typescript@4.5.5 + typescript: 4.5.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils/5.11.0_eslint@8.9.0+typescript@4.5.5: resolution: {integrity: sha512-g2I480tFE1iYRDyMhxPAtLQ9HAn0jjBtipgTCZmd9I9s11OV8CTsG+YfFciuNDcHqm4csbAgC2aVZCHzLxMSUw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2004,9 +2104,27 @@ packages: '@typescript-eslint/scope-manager': 5.11.0 '@typescript-eslint/types': 5.11.0 '@typescript-eslint/typescript-estree': 5.11.0_typescript@4.5.5 - eslint: 8.8.0 + eslint: 8.9.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.8.0 + eslint-utils: 3.0.0_eslint@8.9.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/utils/5.12.0_eslint@8.9.0+typescript@4.5.5: + resolution: {integrity: sha512-k4J2WovnMPGI4PzKgDtQdNrCnmBHpMUFy21qjX2CoPdoBcSBIMvVBr9P2YDP8jOqZOeK3ThOL6VO/sy6jtnvzw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.9 + '@typescript-eslint/scope-manager': 5.12.0 + '@typescript-eslint/types': 5.12.0 + '@typescript-eslint/typescript-estree': 5.12.0_typescript@4.5.5 + eslint: 8.9.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@8.9.0 transitivePeerDependencies: - supports-color - typescript @@ -2017,22 +2135,30 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: '@typescript-eslint/types': 5.11.0 - eslint-visitor-keys: 3.2.0 + eslint-visitor-keys: 3.3.0 dev: true - /@vitejs/plugin-vue/2.2.0_vite@2.8.0+vue@3.2.30: + /@typescript-eslint/visitor-keys/5.12.0: + resolution: {integrity: sha512-cFwTlgnMV6TgezQynx2c/4/tx9Tufbuo9LPzmWqyRC3QC4qTGkAG1C6pBr0/4I10PAI/FlYunI3vJjIcu+ZHMg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.12.0 + eslint-visitor-keys: 3.3.0 + dev: true + + /@vitejs/plugin-vue/2.2.0_vite@2.8.1+vue@3.2.30: resolution: {integrity: sha512-wXigM1EwN2G7rZcwG6kLk9ivvIMhx2363tCEvMBiXcTu5nePM/12hUPVzPb83Uugt6U+zom1gTpJopi/Ow/jwg==} engines: {node: '>=12.0.0'} peerDependencies: vite: ^2.5.10 vue: ^3.2.25 dependencies: - vite: 2.8.0 + vite: 2.8.1 vue: 3.2.30 dev: true - /@vitest/ui/0.3.0: - resolution: {integrity: sha512-kOoqWgeRhLry0t8LeldvxMrGKsIuOR3NMHGfoFQJcTrUsNoynfPu7/FMYfTrfVIYr3LShIUeneQQLLcGiw/bCw==} + /@vitest/ui/0.3.5: + resolution: {integrity: sha512-OO06tHPDolQpcYWAwU89T4azOTyTi65XxEXwfxrcSvGtMdk++U41D7WSggeOQ4UcbexHTaXeHuEEEZ3IF4W3IA==} dependencies: sirv: 2.0.2 dev: true @@ -2088,10 +2214,10 @@ packages: upath: 2.0.1 dev: true - /@vscode/emmet-helper/2.8.3: - resolution: {integrity: sha512-dkTSL+BaBBS8gFgPm/GMOU+XfxaMyI+Fl1IUYxEi8Iv24RfHf9/q2eCpV2hs7sncLcoKWEbMYe5gv4Ppmp2Oxw==} + /@vscode/emmet-helper/2.8.4: + resolution: {integrity: sha512-lUki5QLS47bz/U8IlG9VQ+1lfxMtxMZENmU5nu4Z71eOD5j9FK0SmYGL5NiVJg9WBWeAU0VxRADMY2Qpq7BfVg==} dependencies: - emmet: 2.3.5 + emmet: 2.3.6 jsonc-parser: 2.3.1 vscode-languageserver-textdocument: 1.0.4 vscode-languageserver-types: 3.16.0 @@ -2133,8 +2259,8 @@ packages: '@vue/compiler-dom': 3.2.30 '@vue/shared': 3.2.30 - /@vue/devtools-api/6.0.4: - resolution: {integrity: sha512-vk+gHlZCyMwLVwon4gnk8HY1dTU6xyNmxuv36QvVfNxw2sOMof6lD7yKH0KTelPpxCypMAQ3DxxHsEl9zEMYUA==} + /@vue/devtools-api/6.0.8: + resolution: {integrity: sha512-bzei608bPVQE2yq9Ghrjn/dnpf27mWfrr0q0ZQiuZoO3LQqFG0T1xSGz+9vw1j9KAZM2Cu9vdQMkddDxqzZGNg==} dev: false /@vue/reactivity-transform/3.2.30: @@ -2200,7 +2326,6 @@ packages: '@vueuse/shared': 7.6.1_vue@3.2.30 vue: 3.2.30 vue-demi: 0.12.1_vue@3.2.30 - dev: false /@vueuse/head/0.7.5_vue@3.2.30: resolution: {integrity: sha512-L+XQ5Act0nT/ZyO8Qo10J4FyM1qPOyQb6MT4MMn6+AITzrStpmKs/nUDDLJKD/rCcNWl/65XbdQm4T2vKp3VOQ==} @@ -2223,7 +2348,6 @@ packages: dependencies: vue: 3.2.30 vue-demi: 0.12.1_vue@3.2.30 - dev: false /@windicss/config/1.7.0: resolution: {integrity: sha512-jP+SYEUMTcvEQexYAeaIGKWq3sE+yv0myyOCph7Glm/YZE2ZCK1GukI1oDG6fcVer121EQzCY4Rx11trb3oSZg==} @@ -2563,7 +2687,7 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001310 + caniuse-lite: 1.0.30001311 electron-to-chromium: 1.4.68 escalade: 3.1.1 node-releases: 2.0.2 @@ -2623,8 +2747,8 @@ packages: upper-case: 1.1.3 dev: true - /caniuse-lite/1.0.30001310: - resolution: {integrity: sha512-cb9xTV8k9HTIUA3GnPUJCk0meUnrHL5gy5QePfDjxHyNBcnzPzrHFv5GqfP7ue5b1ZyzZL0RJboD6hQlPXjhjg==} + /caniuse-lite/1.0.30001311: + resolution: {integrity: sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==} dev: true /chai/4.3.6: @@ -2635,7 +2759,7 @@ packages: check-error: 1.0.2 deep-eql: 3.0.1 get-func-name: 2.0.0 - loupe: 2.3.3 + loupe: 2.3.4 pathval: 1.1.1 type-detect: 4.0.8 dev: true @@ -2764,7 +2888,6 @@ packages: /common-types/1.31.1: resolution: {integrity: sha512-eixAd22Gmek1dgsPgyqCSjzMAlp8rpSLkb44iEMfOzR9fwGFYEkH+AWOHmwSFxWmO8MvMND/m1jpZX0Wk4+yJA==} - dev: false /compressible/2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} @@ -3130,10 +3253,10 @@ packages: resolution: {integrity: sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==} dev: true - /emmet/2.3.5: - resolution: {integrity: sha512-LcWfTamJnXIdMfLvJEC5Ld3hY5/KHXgv1L1bp6I7eEvB0ZhacHZ1kX0BYovJ8FroEsreLcq7n7kZhRMsf6jkXQ==} + /emmet/2.3.6: + resolution: {integrity: sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A==} dependencies: - '@emmetio/abbreviation': 2.2.2 + '@emmetio/abbreviation': 2.2.3 '@emmetio/css-abbreviation': 2.1.4 dev: true @@ -3442,16 +3565,16 @@ packages: source-map: 0.6.1 dev: true - /eslint-config-prettier/8.3.0_eslint@8.8.0: + /eslint-config-prettier/8.3.0_eslint@8.9.0: resolution: {integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.8.0 + eslint: 8.9.0 dev: true - /eslint-config-standard/17.0.0-0_d98185a972f50d26baaf376f983a6b27: + /eslint-config-standard/17.0.0-0_c8ad1c911fa160b4a9904c4bb416080e: resolution: {integrity: sha512-sf9udec8fkLTnH82SmhZQ3E31e4eJaMW09Mt9fbN3OccXFtvSSbGrltpQgGFVooGHoIdiMzDfp6ZNFd+I6Ob+w==} peerDependencies: eslint: ^8.0.1 @@ -3459,10 +3582,10 @@ packages: eslint-plugin-n: ^14.0.0 eslint-plugin-promise: ^6.0.0 dependencies: - eslint: 8.8.0 - eslint-plugin-import: 2.25.4_eslint@8.8.0 - eslint-plugin-n: 14.0.0_eslint@8.8.0 - eslint-plugin-promise: 6.0.0_eslint@8.8.0 + eslint: 8.9.0 + eslint-plugin-import: 2.25.4_eslint@8.9.0 + eslint-plugin-n: 14.0.0_eslint@8.9.0 + eslint-plugin-promise: 6.0.0_eslint@8.9.0 dev: true /eslint-import-resolver-node/0.3.6: @@ -3480,34 +3603,34 @@ packages: find-up: 2.1.0 dev: true - /eslint-plugin-cypress/2.12.1_eslint@8.8.0: + /eslint-plugin-cypress/2.12.1_eslint@8.9.0: resolution: {integrity: sha512-c2W/uPADl5kospNDihgiLc7n87t5XhUbFDoTl6CfVkmG+kDAb5Ux10V9PoLPu9N+r7znpc+iQlcmAqT1A/89HA==} peerDependencies: eslint: '>= 3.2.1' dependencies: - eslint: 8.8.0 + eslint: 8.9.0 globals: 11.12.0 dev: true - /eslint-plugin-es/4.1.0_eslint@8.8.0: + /eslint-plugin-es/4.1.0_eslint@8.9.0: resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=4.19.1' dependencies: - eslint: 8.8.0 + eslint: 8.9.0 eslint-utils: 2.1.0 regexpp: 3.2.0 dev: true - /eslint-plugin-eslint-comments/3.2.0_eslint@8.8.0: + /eslint-plugin-eslint-comments/3.2.0_eslint@8.9.0: resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} engines: {node: '>=6.5.0'} peerDependencies: eslint: '>=4.19.1' dependencies: escape-string-regexp: 1.0.5 - eslint: 8.8.0 + eslint: 8.9.0 ignore: 5.2.0 dev: true @@ -3517,7 +3640,7 @@ packages: htmlparser2: 7.2.0 dev: true - /eslint-plugin-import/2.25.4_eslint@8.8.0: + /eslint-plugin-import/2.25.4_eslint@8.9.0: resolution: {integrity: sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==} engines: {node: '>=4'} peerDependencies: @@ -3527,39 +3650,39 @@ packages: array.prototype.flat: 1.2.5 debug: 2.6.9 doctrine: 2.1.0 - eslint: 8.8.0 + eslint: 8.9.0 eslint-import-resolver-node: 0.3.6 eslint-module-utils: 2.7.3 has: 1.0.3 is-core-module: 2.8.1 is-glob: 4.0.3 - minimatch: 3.0.5 + minimatch: 3.1.1 object.values: 1.1.5 resolve: 1.22.0 tsconfig-paths: 3.12.0 dev: true - /eslint-plugin-jsonc/2.1.0_eslint@8.8.0: + /eslint-plugin-jsonc/2.1.0_eslint@8.9.0: resolution: {integrity: sha512-ueuFWW+u/hjU9+j5Ov+ZoWIukMlaWrB+MS/wfKYWqKkAVr7U9zYqUu4ZwLh2AHU3+FjvmS8+1Va5bP6J/ERVyg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' dependencies: - eslint: 8.8.0 - eslint-utils: 3.0.0_eslint@8.8.0 + eslint: 8.9.0 + eslint-utils: 3.0.0_eslint@8.9.0 jsonc-eslint-parser: 2.1.0 natural-compare: 1.4.0 dev: true - /eslint-plugin-n/14.0.0_eslint@8.8.0: + /eslint-plugin-n/14.0.0_eslint@8.9.0: resolution: {integrity: sha512-mNwplPLsbaKhHyA0fa/cy8j+oF6bF6l81hzBTWa6JOvPcMNAuIogk2ih6d9tYvWYzyUG+7ZFeChqbzdFpg2QrQ==} engines: {node: '>=12.22.0'} peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.8.0 - eslint-plugin-es: 4.1.0_eslint@8.8.0 - eslint-utils: 3.0.0_eslint@8.8.0 + eslint: 8.9.0 + eslint-plugin-es: 4.1.0_eslint@8.9.0 + eslint-utils: 3.0.0_eslint@8.9.0 ignore: 5.2.0 is-core-module: 2.8.1 minimatch: 3.0.5 @@ -3567,7 +3690,7 @@ packages: semver: 6.3.0 dev: true - /eslint-plugin-prettier/4.0.0_43197c8d12d1d439034cfcf65e1c48c2: + /eslint-plugin-prettier/4.0.0_07b422646bb75d3db791621d4fdbc992: resolution: {integrity: sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==} engines: {node: '>=6.0.0'} peerDependencies: @@ -3578,22 +3701,22 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.8.0 - eslint-config-prettier: 8.3.0_eslint@8.8.0 + eslint: 8.9.0 + eslint-config-prettier: 8.3.0_eslint@8.9.0 prettier: 2.5.1 prettier-linter-helpers: 1.0.0 dev: true - /eslint-plugin-promise/6.0.0_eslint@8.8.0: + /eslint-plugin-promise/6.0.0_eslint@8.9.0: resolution: {integrity: sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - eslint: 8.8.0 + eslint: 8.9.0 dev: true - /eslint-plugin-react/7.28.0_eslint@8.8.0: + /eslint-plugin-react/7.28.0_eslint@8.9.0: resolution: {integrity: sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==} engines: {node: '>=4'} peerDependencies: @@ -3602,7 +3725,7 @@ packages: array-includes: 3.1.4 array.prototype.flatmap: 1.2.5 doctrine: 2.1.0 - eslint: 8.8.0 + eslint: 8.9.0 estraverse: 5.3.0 jsx-ast-utils: 3.2.1 minimatch: 3.0.5 @@ -3616,7 +3739,7 @@ packages: string.prototype.matchall: 4.0.6 dev: true - /eslint-plugin-unicorn/40.1.0_eslint@8.8.0: + /eslint-plugin-unicorn/40.1.0_eslint@8.9.0: resolution: {integrity: sha512-y5doK2DF9Sr5AqKEHbHxjFllJ167nKDRU01HDcWyv4Tnmaoe9iNxMrBnaybZvWZUaE3OC5Unu0lNIevYamloig==} engines: {node: '>=12'} peerDependencies: @@ -3625,8 +3748,8 @@ packages: '@babel/helper-validator-identifier': 7.16.7 ci-info: 3.3.0 clean-regexp: 1.0.0 - eslint: 8.8.0 - eslint-utils: 3.0.0_eslint@8.8.0 + eslint: 8.9.0 + eslint-utils: 3.0.0_eslint@8.9.0 esquery: 1.4.0 indent-string: 4.0.0 is-builtin-module: 3.1.0 @@ -3639,29 +3762,29 @@ packages: strip-indent: 3.0.0 dev: true - /eslint-plugin-vue/8.4.1_eslint@8.8.0: + /eslint-plugin-vue/8.4.1_eslint@8.9.0: resolution: {integrity: sha512-nmWOhNmDx9TZ+yP9ZhezTkZUupSHsYA2TocRm+efPSXMOyFrVczVlaIuQcLBjCtI8CbkBiUQ3VcyQsjlIhDrhA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 dependencies: - eslint: 8.8.0 - eslint-utils: 3.0.0_eslint@8.8.0 + eslint: 8.9.0 + eslint-utils: 3.0.0_eslint@8.9.0 natural-compare: 1.4.0 semver: 7.3.5 - vue-eslint-parser: 8.2.0_eslint@8.8.0 + vue-eslint-parser: 8.2.0_eslint@8.9.0 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-yml/0.12.0_eslint@8.8.0: + /eslint-plugin-yml/0.12.0_eslint@8.9.0: resolution: {integrity: sha512-aS82M+diohZTusadiByzh/bKDrfi+Y6VBQkD3ym/7JH+KF9WUB9qKCizLfTaCACwtRrHpqaLz3G8GKmslshyiw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' dependencies: debug: 4.3.3 - eslint: 8.8.0 + eslint: 8.9.0 lodash: 4.17.21 natural-compare: 1.4.0 yaml-eslint-parser: 0.5.0 @@ -3677,8 +3800,8 @@ packages: estraverse: 4.3.0 dev: true - /eslint-scope/7.1.0: - resolution: {integrity: sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==} + /eslint-scope/7.1.1: + resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: esrecurse: 4.3.0 @@ -3692,13 +3815,13 @@ packages: eslint-visitor-keys: 1.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.8.0: + /eslint-utils/3.0.0_eslint@8.9.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.8.0 + eslint: 8.9.0 eslint-visitor-keys: 2.1.0 dev: true @@ -3712,17 +3835,17 @@ packages: engines: {node: '>=10'} dev: true - /eslint-visitor-keys/3.2.0: - resolution: {integrity: sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==} + /eslint-visitor-keys/3.3.0: + resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.8.0: - resolution: {integrity: sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==} + /eslint/8.9.0: + resolution: {integrity: sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint/eslintrc': 1.0.5 + '@eslint/eslintrc': 1.1.0 '@humanwhocodes/config-array': 0.9.3 ajv: 6.12.6 chalk: 4.1.2 @@ -3730,10 +3853,10 @@ packages: debug: 4.3.3 doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 7.1.0 - eslint-utils: 3.0.0_eslint@8.8.0 - eslint-visitor-keys: 3.2.0 - espree: 9.3.0 + eslint-scope: 7.1.1 + eslint-utils: 3.0.0_eslint@8.9.0 + eslint-visitor-keys: 3.3.0 + espree: 9.3.1 esquery: 1.4.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -3749,7 +3872,7 @@ packages: json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 - minimatch: 3.0.5 + minimatch: 3.1.1 natural-compare: 1.4.0 optionator: 0.9.1 regexpp: 3.2.0 @@ -3770,13 +3893,13 @@ packages: eslint-visitor-keys: 1.3.0 dev: true - /espree/9.3.0: - resolution: {integrity: sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==} + /espree/9.3.1: + resolution: {integrity: sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.7.0 acorn-jsx: 5.3.2_acorn@8.7.0 - eslint-visitor-keys: 3.2.0 + eslint-visitor-keys: 3.3.0 dev: true /esprima/4.0.1: @@ -3997,7 +4120,6 @@ packages: '@floating-ui/dom': 0.1.10 vue: 3.2.30 vue-resize: 2.0.0-alpha.1_vue@3.2.30 - dev: false /follow-redirects/1.14.8: resolution: {integrity: sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==} @@ -4141,7 +4263,7 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.0.5 + minimatch: 3.1.1 once: 1.4.0 path-is-absolute: 1.0.1 dev: true @@ -4152,7 +4274,7 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.0.5 + minimatch: 3.1.1 once: 1.4.0 path-is-absolute: 1.0.1 dev: true @@ -4421,7 +4543,6 @@ packages: resolution: {integrity: sha512-rdI+5Zuxb7eYKAkU6PxoxqW0TzdFxodMHaUNAmuaxaCg2ngZTKwBTN5LqimfxNyRCOZWyv0DGd7DzNE9mZXVQA==} dependencies: common-types: 1.31.1 - dev: false /inflight/1.0.6: resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} @@ -4663,7 +4784,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 17.0.16 + '@types/node': 17.0.17 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true @@ -4808,8 +4929,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.7.0 - eslint-visitor-keys: 3.2.0 - espree: 9.3.0 + eslint-visitor-keys: 3.3.0 + espree: 9.3.1 semver: 7.3.5 dev: true @@ -4962,8 +5083,8 @@ packages: resolution: {integrity: sha512-RicKUuLwZVNZ6ZdJHgIZnSeA05p8qWc5NW0uR96mpPIjN9WDLUg9+kj1esQU1GkPn9iLZVKatSQK5gyiaFHgJA==} dev: true - /loupe/2.3.3: - resolution: {integrity: sha512-krIV4Cf1BIGIx2t1e6tucThhrBemUnIUjMtD2vN4mrMxnxpBvrcosBSpooqunBqP/hOEEV1w/Cr1YskGtqw5Jg==} + /loupe/2.3.4: + resolution: {integrity: sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==} dependencies: get-func-name: 2.0.0 dev: true @@ -5027,6 +5148,17 @@ packages: engines: {node: '>= 0.6'} dev: true + /meili-searchbar/2.2.1_vue@3.2.30: + resolution: {integrity: sha512-2i8A+7xQFlRzqs55A32v468gh+pZ7uFXAfV7yV8mFRefJjN760jT4dBrh2LwQHJVUvHPJ45GHeIn9jShuUVvww==} + dependencies: + '@vueuse/core': 7.6.1_vue@3.2.30 + floating-vue: 2.0.0-beta.6_vue@3.2.30 + native-dash: 1.22.0 + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + /meilisearch/0.24.0: resolution: {integrity: sha512-qME1dsHZePBQi8qFdhbilcFzaL+oZJgUuls+FZ23hHpdhJI+iMFSmjjcfsxq5hdg2qczbCXv7yAo3Sh8xgfkgA==} dependencies: @@ -5102,6 +5234,12 @@ packages: brace-expansion: 1.1.11 dev: true + /minimatch/3.1.1: + resolution: {integrity: sha512-reLxBcKUPNBnc/sVtAbxgRVFSegoGeLaSjmphNhcwcolhYLRgtJscn5mRl6YRZNQv40Y7P6JM2YhSIsbL9OB5A==} + dependencies: + brace-expansion: 1.1.11 + dev: true + /minimist/1.2.5: resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} @@ -5145,11 +5283,10 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - /native-dash/1.21.5: - resolution: {integrity: sha512-2fG0hVIXdlDiPxSdlp4YkLwc0HOYfrxSPDQ+2th2wH7ieMZf/LfF7kVe+dIDQE+3WDo84D13vpQW8WW8VFMYig==} + /native-dash/1.22.0: + resolution: {integrity: sha512-8GUM8+gGbqXu8oVyglbinZw2wECpmFAYTVsFwMYNJpWaHmd84suWJDXhMpbNf+QC/06jgqqOajRAHakfEcWyAg==} dependencies: inferred-types: 0.18.4 - dev: false /natural-compare/1.4.0: resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} @@ -5219,7 +5356,7 @@ packages: chalk: 2.4.2 cross-spawn: 6.0.5 memorystream: 0.3.1 - minimatch: 3.0.5 + minimatch: 3.1.1 pidtree: 0.3.1 read-pkg: 3.0.0 shell-quote: 1.7.3 @@ -5558,7 +5695,7 @@ packages: typescript: optional: true dependencies: - '@vue/devtools-api': 6.0.4 + '@vue/devtools-api': 6.0.8 typescript: 4.5.5 vue: 3.2.30 vue-demi: 0.12.1_vue@3.2.30 @@ -5574,8 +5711,8 @@ packages: engines: {node: '>=4'} dev: true - /postcss-load-config/3.1.1_ts-node@10.5.0: - resolution: {integrity: sha512-c/9XYboIbSEUZpiD1UQD0IKiUe8n9WHYV7YFe7X7J+ZwCsEKkUJSFWjS9hBU1RR9THR7jMXst8sxiqP0jjo2mg==} + /postcss-load-config/3.1.3_ts-node@10.5.0: + resolution: {integrity: sha512-5EYgaM9auHGtO//ljHH+v/aC/TQ5LHXtL7bQajNAUBKUVKiYE8rYpFms7+V26D9FncaGe2zwCoPQsFKb5zF/Hw==} engines: {node: '>= 10'} peerDependencies: ts-node: '>=9.0.0' @@ -5584,7 +5721,7 @@ packages: optional: true dependencies: lilconfig: 2.0.4 - ts-node: 10.5.0_d9704c9be36ede869b5c33ef6688872e + ts-node: 10.5.0_31a32bd81d8bbfc3c2c321de918dd405 yaml: 1.10.2 dev: true @@ -5979,22 +6116,22 @@ packages: glob: 7.2.0 dev: true - /rollup-plugin-terser/7.0.2_rollup@2.67.1: + /rollup-plugin-terser/7.0.2_rollup@2.67.2: resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} peerDependencies: rollup: ^2.0.0 dependencies: '@babel/code-frame': 7.16.7 jest-worker: 26.6.2 - rollup: 2.67.1 + rollup: 2.67.2 serialize-javascript: 4.0.0 terser: 5.10.0 transitivePeerDependencies: - acorn dev: true - /rollup/2.67.1: - resolution: {integrity: sha512-1Sbcs4OuW+aD+hhqpIRl+RqooIpF6uQcfzU/QSI7vGkwADY6cM4iLsBGRM2CGLXDTDN5y/yShohFmnKegSPWzg==} + /rollup/2.67.2: + resolution: {integrity: sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==} engines: {node: '>=10.0.0'} hasBin: true optionalDependencies: @@ -6532,7 +6669,7 @@ packages: code-block-writer: 11.0.0 dev: true - /ts-node/10.5.0_d9704c9be36ede869b5c33ef6688872e: + /ts-node/10.5.0_31a32bd81d8bbfc3c2c321de918dd405: resolution: {integrity: sha512-6kEJKwVxAJ35W4akuiysfKwKmjkbYxwQMTBaAxo9KKAx/Yd26mPUyhGz3ji+EsJoAgrLqVsYHNuuYwQe22lbtw==} hasBin: true peerDependencies: @@ -6551,7 +6688,7 @@ packages: '@tsconfig/node12': 1.0.9 '@tsconfig/node14': 1.0.1 '@tsconfig/node16': 1.0.2 - '@types/node': 14.18.10 + '@types/node': 14.18.12 acorn: 8.7.0 acorn-walk: 8.2.0 arg: 4.1.3 @@ -6597,9 +6734,9 @@ packages: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 3.1.1_ts-node@10.5.0 + postcss-load-config: 3.1.3_ts-node@10.5.0 resolve-from: 5.0.0 - rollup: 2.67.1 + rollup: 2.67.2 source-map: 0.7.3 sucrase: 3.20.3 tree-kill: 1.2.2 @@ -6748,7 +6885,7 @@ packages: engines: {node: '>= 0.8'} dev: true - /unplugin-auto-import/0.5.11_@vueuse+core@7.6.1+vite@2.8.0: + /unplugin-auto-import/0.5.11_@vueuse+core@7.6.1+vite@2.8.1: resolution: {integrity: sha512-MJ3POLe/IysRHF4yd32FkKDoxqSRoiuIHm89ys67B8FLuz2Pvh9poeqTVe6IhJsNxwv0+GSdFfj5Dpq24lhm4g==} engines: {node: '>=14'} peerDependencies: @@ -6763,7 +6900,7 @@ packages: local-pkg: 0.4.1 magic-string: 0.25.7 resolve: 1.22.0 - unplugin: 0.3.2_vite@2.8.0 + unplugin: 0.3.2_vite@2.8.1 transitivePeerDependencies: - esbuild - rollup @@ -6771,7 +6908,7 @@ packages: - webpack dev: true - /unplugin-icons/0.13.1_74c57c6669a9652c267f522b0d6c9a3b: + /unplugin-icons/0.13.1_f38b2674125d22360785c84d0f6f797d: resolution: {integrity: sha512-Y7ZOjTUvLdY4qUQNDo4OmkxjCh2coNbcAeWfFW66EZW7cJiBI6vU8j4cBAsyqUEwMdFL3q/kwowCRgD6BAaRyQ==} peerDependencies: '@svgr/core': '>=5.5.0' @@ -6795,7 +6932,7 @@ packages: debug: 4.3.3 kolorist: 1.5.1 local-pkg: 0.4.1 - unplugin: 0.3.2_vite@2.8.0 + unplugin: 0.3.2_vite@2.8.1 transitivePeerDependencies: - esbuild - rollup @@ -6804,7 +6941,7 @@ packages: - webpack dev: true - /unplugin-vue-components/0.17.18_vite@2.8.0+vue@3.2.30: + /unplugin-vue-components/0.17.18_vite@2.8.1+vue@3.2.30: resolution: {integrity: sha512-4wvJnSShTXCnZpO1G6h0DlHjBXap0JqzFyU84guMT6EH0shUZZ3TAta4pDa8nNeWAtcJVTF9uQswePq1elhpKQ==} engines: {node: '>=14'} peerDependencies: @@ -6826,7 +6963,7 @@ packages: magic-string: 0.25.7 minimatch: 3.0.5 resolve: 1.22.0 - unplugin: 0.3.2_vite@2.8.0 + unplugin: 0.3.2_vite@2.8.1 vue: 3.2.30 transitivePeerDependencies: - esbuild @@ -6836,7 +6973,7 @@ packages: - webpack dev: true - /unplugin/0.3.2_vite@2.8.0: + /unplugin/0.3.2_vite@2.8.1: resolution: {integrity: sha512-5d0DMYNKZU+S9eZUiBfw6Co32eRg8myUgBPoWSqG/wDFCUE/WznfSsJnZWi1P9l69x4uLJqt2qVq1xW/AsXFrw==} peerDependencies: esbuild: '>=0.13' @@ -6853,7 +6990,7 @@ packages: webpack: optional: true dependencies: - vite: 2.8.0 + vite: 2.8.1 webpack-virtual-modules: 0.4.3 dev: true @@ -6906,7 +7043,7 @@ packages: engines: {node: '>= 0.8'} dev: true - /vite-plugin-dts/0.9.9_vite@2.8.0: + /vite-plugin-dts/0.9.9_vite@2.8.2: resolution: {integrity: sha512-HzLTCBbsN9gotphtIe97TCigeco6aGLBoeSHdxD9QGGl8prO7uykus0fphLkjWCbFlrerb8Uxp9fu82BfIiaIg==} engines: {node: '>=12.0.0'} peerDependencies: @@ -6915,11 +7052,11 @@ packages: fast-glob: 3.2.11 fs-extra: 10.0.0 ts-morph: 13.0.3 - vite: 2.8.0 + vite: 2.8.2 dev: true - /vite-plugin-inspect/0.3.13_vite@2.8.0: - resolution: {integrity: sha512-Naie3Rx/0IbmQSknfQPVrvWKiar7fCu50u+uLcUgt54yX0espduLDnI8IEtOYlsCA4gHs93IYKtxFDTxAThmYw==} + /vite-plugin-inspect/0.3.14_vite@2.8.1: + resolution: {integrity: sha512-oRjltmm1nUgkHmlGLgfSAuPiXA/FqC7daURJ+faY498r3mwnXrtcfe6Bg5khANQ0iss9Cn1uV6+W9c85noVq0g==} engines: {node: '>=14'} peerDependencies: vite: ^2.0.0 @@ -6929,12 +7066,28 @@ packages: kolorist: 1.5.1 sirv: 2.0.2 ufo: 0.7.10 - vite: 2.8.0 + vite: 2.8.1 transitivePeerDependencies: - supports-color dev: true - /vite-plugin-md/0.11.8_vite@2.8.0: + /vite-plugin-inspect/0.3.14_vite@2.8.2: + resolution: {integrity: sha512-oRjltmm1nUgkHmlGLgfSAuPiXA/FqC7daURJ+faY498r3mwnXrtcfe6Bg5khANQ0iss9Cn1uV6+W9c85noVq0g==} + engines: {node: '>=14'} + peerDependencies: + vite: ^2.0.0 + dependencies: + '@rollup/pluginutils': 4.1.2 + debug: 4.3.3 + kolorist: 1.5.1 + sirv: 2.0.2 + ufo: 0.7.10 + vite: 2.8.2 + transitivePeerDependencies: + - supports-color + dev: true + + /vite-plugin-md/0.11.8_vite@2.8.1: resolution: {integrity: sha512-eFk4Ox8IKuT+7benAcwLvGcYt/T4We2UDmQmxvCrhABJpQSbh44MitD1Wu6w733VKgSZAO7wd8IuoA20yXkXVQ==} peerDependencies: vite: ^2.0.0 @@ -6944,10 +7097,10 @@ packages: '@types/markdown-it': 12.2.3 gray-matter: 4.0.3 markdown-it: 12.3.2 - vite: 2.8.0 + vite: 2.8.1 dev: true - /vite-plugin-pages/0.20.2_74c57c6669a9652c267f522b0d6c9a3b: + /vite-plugin-pages/0.20.2_f38b2674125d22360785c84d0f6f797d: resolution: {integrity: sha512-A/N6Pez9sMzt7ZEfd1H7P9tmP6LrZwXMexV8xSiRahnUeNw+gz0W2dsPLJDZBvcixDZqoK8ggKdmyxgVBuTAfg==} peerDependencies: '@vue/compiler-sfc': '>=3' @@ -6962,13 +7115,13 @@ packages: fast-glob: 3.2.11 json5: 2.2.0 local-pkg: 0.4.1 - vite: 2.8.0 + vite: 2.8.1 yaml: 2.0.0-10 transitivePeerDependencies: - supports-color dev: true - /vite-plugin-pwa/0.11.13_vite@2.8.0: + /vite-plugin-pwa/0.11.13_vite@2.8.1: resolution: {integrity: sha512-Ssj14m3TRVLfkFEAWSMcFE2d1cSdEZyrVTzfY2lSL+umHYvcIFHVDAY143sygtBCb44OPczsAOmWwBTxwOvh7g==} peerDependencies: vite: ^2.0.0 @@ -6976,8 +7129,8 @@ packages: debug: 4.3.3 fast-glob: 3.2.11 pretty-bytes: 5.6.0 - rollup: 2.67.1 - vite: 2.8.0 + rollup: 2.67.2 + vite: 2.8.1 workbox-build: 6.4.2 workbox-window: 6.4.2 transitivePeerDependencies: @@ -6986,7 +7139,7 @@ packages: - supports-color dev: true - /vite-plugin-vue-layouts/0.6.0_96c99e3b7a55d9fa64f74317a359b00e: + /vite-plugin-vue-layouts/0.6.0_861efee176eccc75a49e11466b75d03a: resolution: {integrity: sha512-7QX7o/NpCfs+hyXphwYfmPqAEQ6qd4uXsvI0VsovjGT2eCoEE5dMdP6L+uqqNWY4uqv7oCvtinecZmbzZv/9Rg==} peerDependencies: vite: ^2.5.0 @@ -6996,14 +7149,14 @@ packages: '@vue/compiler-sfc': 3.2.30 debug: 4.3.3 fast-glob: 3.2.11 - vite: 2.8.0 + vite: 2.8.1 vue: 3.2.30 vue-router: 4.0.12_vue@3.2.30 transitivePeerDependencies: - supports-color dev: true - /vite-plugin-windicss/1.7.0_vite@2.8.0: + /vite-plugin-windicss/1.7.0_vite@2.8.1: resolution: {integrity: sha512-1ps7hk6Pr9TqsW9Y+QXmJ9PMowVLjM0h32c+jh9vdQr5Jzyim3hHivR0rXSkDV9znIB9RkjRQD1znRbAMX0OcQ==} peerDependencies: vite: ^2.0.1 @@ -7011,13 +7164,13 @@ packages: '@windicss/plugin-utils': 1.7.0 debug: 4.3.3 kolorist: 1.5.1 - vite: 2.8.0 + vite: 2.8.1 windicss: 3.4.3 transitivePeerDependencies: - supports-color dev: true - /vite-ssg/0.17.10_dd02a634c6d9f894c7a4243a6abbc11a: + /vite-ssg/0.17.10_2a1f4eb68d7efe0f1402d91afc414ace: resolution: {integrity: sha512-gPcw5RLmAq5CwZ9Q/Ca9kJWUm6KdxhkNRBzm8P4bGDCRQLNQkgTiQmK7ZwsdqD7C8bah4CMBFDeqz2MKSQintw==} engines: {node: '>=14.0.0'} hasBin: true @@ -7039,7 +7192,7 @@ packages: jsdom: 19.0.0 kolorist: 1.5.1 prettier: 2.5.1 - vite: 2.8.0 + vite: 2.8.1 vue: 3.2.30 vue-router: 4.0.12_vue@3.2.30 yargs: 17.3.1 @@ -7050,8 +7203,8 @@ packages: - utf-8-validate dev: true - /vite/2.8.0: - resolution: {integrity: sha512-ed5rjyeysttuPJX/aKSA0gTB/8ZKLM5xF6FtEuKy1B9DiQbDNFMVMQxnb9JesgBPUMMIJxC8w5KZ/KNWLKFXoA==} + /vite/2.8.1: + resolution: {integrity: sha512-Typ8qjUnW0p53gBsJpisrKcZlEbUPZATja9BG6Z09QZjg9YrnEn/htkr/VH4WhnH7eNUQeSD+wKI1lHzQRWskw==} engines: {node: '>=12.2.0'} hasBin: true peerDependencies: @@ -7069,46 +7222,37 @@ packages: esbuild: 0.14.21 postcss: 8.4.6 resolve: 1.22.0 - rollup: 2.67.1 + rollup: 2.67.2 optionalDependencies: fsevents: 2.3.2 dev: true - /vitest/0.3.0_@vitest+ui@0.3.0: - resolution: {integrity: sha512-ybsOkts6kCLaNfMkLrJeCSuu8A/fC4nFJKB54JiN1nNls2QsLYKrVeJTq7dGFTnVSQIVDQ+6KuGxzsC9e6EvtA==} - engines: {node: '>=14.14.0'} + /vite/2.8.2: + resolution: {integrity: sha512-zawfykcPVPYva4KusIWORNLr324Qx86/3NpfQSIOJdjnL5pYhwDoImLYMOh4lFLcP/7//tNuWM2vx2F5OSVC9w==} + engines: {node: '>=12.2.0'} hasBin: true peerDependencies: - '@vitest/ui': '*' - c8: '*' - happy-dom: '*' - jsdom: '*' + less: '*' + sass: '*' + stylus: '*' peerDependenciesMeta: - '@vitest/ui': + less: optional: true - c8: + sass: optional: true - happy-dom: - optional: true - jsdom: + stylus: optional: true dependencies: - '@types/chai': 4.3.0 - '@types/chai-subset': 1.3.3 - '@vitest/ui': 0.3.0 - chai: 4.3.6 - local-pkg: 0.4.1 - tinypool: 0.1.2 - tinyspy: 0.2.10 - vite: 2.8.0 - transitivePeerDependencies: - - less - - sass - - stylus + esbuild: 0.14.21 + postcss: 8.4.6 + resolve: 1.22.0 + rollup: 2.67.2 + optionalDependencies: + fsevents: 2.3.2 dev: true - /vitest/0.3.0_jsdom@19.0.0: - resolution: {integrity: sha512-ybsOkts6kCLaNfMkLrJeCSuu8A/fC4nFJKB54JiN1nNls2QsLYKrVeJTq7dGFTnVSQIVDQ+6KuGxzsC9e6EvtA==} + /vitest/0.3.2_jsdom@19.0.0: + resolution: {integrity: sha512-Xc0u8BVPBdD029uDcLSYDvy1MFenC6V8WvTJOGdld6NNWgz/swgsMvwZNzftsDohmHLgDyck8A+TaQdDd1tNwA==} engines: {node: '>=14.14.0'} hasBin: true peerDependencies: @@ -7133,7 +7277,40 @@ packages: local-pkg: 0.4.1 tinypool: 0.1.2 tinyspy: 0.2.10 - vite: 2.8.0 + vite: 2.8.1 + transitivePeerDependencies: + - less + - sass + - stylus + dev: true + + /vitest/0.3.5_@vitest+ui@0.3.5: + resolution: {integrity: sha512-IIYupM5RAN9H44F5k/Yz0DEORHPJC8qwdi6sQmcdjrxqfxIHypq9PoutQQrW1WKW9O9yUNYG5VGHeHlqAXa9wg==} + engines: {node: '>=14.14.0'} + hasBin: true + peerDependencies: + '@vitest/ui': '*' + c8: '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@vitest/ui': + optional: true + c8: + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.0 + '@types/chai-subset': 1.3.3 + '@vitest/ui': 0.3.5 + chai: 4.3.6 + local-pkg: 0.4.1 + tinypool: 0.1.2 + tinyspy: 0.2.10 + vite: 2.8.2 transitivePeerDependencies: - less - sass @@ -7145,8 +7322,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /vscode-css-languageservice/5.1.12: - resolution: {integrity: sha512-293C5C2732Rbhh3opTs+nQBpC5Dd+oYrEA8lc0OWdyt40oYmJ331FV7NMF1SLFSIcOFB5XveLiWUZak2oyc49Q==} + /vscode-css-languageservice/5.1.13: + resolution: {integrity: sha512-FA0foqMzMmEoO0WJP+MjoD4dRERhKS+Ag+yBrtmWQDmw2OuZ1R/5FkvI/XdTkCpHmTD9VMczugpHRejQyTXCNQ==} dependencies: vscode-languageserver-textdocument: 1.0.4 vscode-languageserver-types: 3.16.0 @@ -7242,11 +7419,11 @@ packages: '@volar/source-map': 0.31.2 '@volar/transforms': 0.31.2 '@volar/vue-code-gen': 0.31.2 - '@vscode/emmet-helper': 2.8.3 + '@vscode/emmet-helper': 2.8.4 '@vue/reactivity': 3.2.30 '@vue/shared': 3.2.30 upath: 2.0.1 - vscode-css-languageservice: 5.1.12 + vscode-css-languageservice: 5.1.13 vscode-html-languageservice: 4.2.1 vscode-json-languageservice: 4.2.0 vscode-languageserver-protocol: 3.17.0-next.14 @@ -7268,19 +7445,18 @@ packages: optional: true dependencies: vue: 3.2.30 - dev: false - /vue-eslint-parser/8.2.0_eslint@8.8.0: + /vue-eslint-parser/8.2.0_eslint@8.9.0: resolution: {integrity: sha512-hvl8OVT8imlKk/lQyhkshqwQQChzHETcBd5abiO4ePw7ib7QUZLfW+2TUrJHKUvFOCFRJrDin5KJO9OHzB5bRQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' dependencies: debug: 4.3.3 - eslint: 8.8.0 - eslint-scope: 7.1.0 - eslint-visitor-keys: 3.2.0 - espree: 9.3.0 + eslint: 8.9.0 + eslint-scope: 7.1.1 + eslint-visitor-keys: 3.3.0 + espree: 9.3.1 esquery: 1.4.0 lodash: 4.17.21 semver: 7.3.5 @@ -7297,7 +7473,7 @@ packages: '@intlify/core-base': 9.1.9 '@intlify/shared': 9.1.9 '@intlify/vue-devtools': 9.1.9 - '@vue/devtools-api': 6.0.4 + '@vue/devtools-api': 6.0.8 vue: 3.2.30 dev: false @@ -7307,14 +7483,13 @@ packages: vue: ^3.0.0 dependencies: vue: 3.2.30 - dev: false /vue-router/4.0.12_vue@3.2.30: resolution: {integrity: sha512-CPXvfqe+mZLB1kBWssssTiWg4EQERyqJZes7USiqfW9B5N2x+nHlnsM1D3b5CaJ6qgCvMmYJnz+G0iWjNCvXrg==} peerDependencies: vue: ^3.0.0 dependencies: - '@vue/devtools-api': 6.0.4 + '@vue/devtools-api': 6.0.8 vue: 3.2.30 dev: false @@ -7498,9 +7673,9 @@ packages: '@babel/core': 7.17.2 '@babel/preset-env': 7.16.11_@babel+core@7.17.2 '@babel/runtime': 7.17.2 - '@rollup/plugin-babel': 5.3.0_@babel+core@7.17.2+rollup@2.67.1 - '@rollup/plugin-node-resolve': 11.2.1_rollup@2.67.1 - '@rollup/plugin-replace': 2.4.2_rollup@2.67.1 + '@rollup/plugin-babel': 5.3.0_@babel+core@7.17.2+rollup@2.67.2 + '@rollup/plugin-node-resolve': 11.2.1_rollup@2.67.2 + '@rollup/plugin-replace': 2.4.2_rollup@2.67.2 '@surma/rollup-plugin-off-main-thread': 2.2.3 ajv: 8.10.0 common-tags: 1.8.2 @@ -7509,8 +7684,8 @@ packages: glob: 7.2.0 lodash: 4.17.21 pretty-bytes: 5.6.0 - rollup: 2.67.1 - rollup-plugin-terser: 7.0.2_rollup@2.67.1 + rollup: 2.67.2 + rollup-plugin-terser: 7.0.2_rollup@2.67.2 source-map: 0.8.0-beta.0 source-map-url: 0.4.1 stringify-object: 3.3.0 @@ -7681,7 +7856,7 @@ packages: resolution: {integrity: sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - eslint-visitor-keys: 3.2.0 + eslint-visitor-keys: 3.3.0 lodash: 4.17.21 yaml: 1.10.2 dev: true diff --git a/tauri-search.code-workspace b/tauri-search.code-workspace index 0049db2..7d5bb50 100644 --- a/tauri-search.code-workspace +++ b/tauri-search.code-workspace @@ -11,6 +11,10 @@ { "name": "📚 Docs", "path": "packages/docs" + }, + { + "name": "🦀 scraper", + "path": "packages/scraper" } ], "settings": {